我有一个名为 PrintJob
的实体,它有一个 ProductId
字段(以及其他字段)。当我创建该实体的新实例并设置所有字段,然后使用 persist 和 flush 时,我收到一条错误消息,指出 ProductId 不能为空。
我在 $productId
变量上执行了一个 var_dump()
,结果是 47。我还在getProductId()
在新实体上(在持久化/刷新之前)并且值仍然是 47。
我认为问题在于 PrintJob
实体和 Product
实体之间的关系。以下是 PrintJob
实体的关系:
/**
* @OneToOne(targetEntity="Product")
* @JoinColumn(name="ProductId", referencedColumnName="ProductId")
*/
private $product;
我在某处读到,在构造函数中,您需要在创建新实体(而不是加载现有实体)时将关系设置为空集合。这是我尝试做的:
public function __construct()
{
$this->product = new \Doctrine\Common\Collections\ArrayCollection();
}
但是,我得到一个错误:
A new entity was found through a relationship that was not configured to cascade persist operations: Doctrine\Common\Collections\ArrayCollection@000000002cb4568d00000000e92b0fce. Explicitly persist the new entity or configure cascading persist operations on the relationship.
任何帮助将不胜感激。我发现的唯一选择是不使用关系 :(
我正在使用 Doctrine 2.0.7。
附加信息:
我不是在创建新的产品实体;新的 PrintJob 正在通过 ProductId 链接。
这是我创建实体的方式 - 如果有用的话,我可以在代码中包含很多其他字段,但我想它们不会有用,因为问题只发生在 ProductId 上......
// convert this quote to a print job
$printJob = new \Dpp\Model\PrintJob;
$printJob->setProductId($productId);
// ... other fields ...
\Dpp\System\Core::getEm()->persist($printJob);
\Dpp\System\Core::getEm()->flush();
\Dpp\System\Core::getEm() 返回 EntityManager。
PrintJob到Product的映射部分:
/**
* @OneToOne(targetEntity="Product", cascade={"persist"})
* @JoinColumn(name="ProductId", referencedColumnName="ProductId")
*/
private $product;
没有从 Product 到 PrintJob 的等效映射。
产品实体 - 仅列:
namespace Dpp\Model;
/**
* @Entity
* @Table(name="Brd_Products")
*/
class Product
{
/**
* @Id @Column(type="integer", name="ProductId")
* @GeneratedValue
*/
private $productId;
附加信息#2:
@JohnM2 指出我的关联设置不正确。所以,这就是我现在拥有的。
\Dpp\Model\PrintJob
/**
* @OneToOne(targetEntity="Product", cascade={"persist"})
* @JoinColumn(name="ProductId", referencedColumnName="ProductId")
*/
private $product;
/**
* @return \Dpp\Model\Product
*/
public function getProduct()
{
return $this->product;
}
/**
* @param \Dpp\Model\Product $product
* @return void
*/
public function setProduct($product)
{
$this->product = $product;
}
\Dpp\Model\Product
/**
* @Id @Column(type="integer", name="ProductId")
* @GeneratedValue
*/
private $productId;
public function getProductId()
{
return $this->productId;
}
保存新实体的代码:
$productEntity = \Dpp\Query\Product::getById($productId);
$printJob = new \Dpp\Model\PrintJob;
$printJob->setProduct($productEntity);
\Dpp\System\Core::getEm()->persist($printJob);
\Dpp\System\Core::getEm()->flush();
第一行返回\Dpp\Model\Product 的一个实例。我检查了 $productId 是否已设置并且 $productEntity 是否已正确填充。
不幸的是,我现在在“persist”行收到一个错误:
Property productId does not exist
我有一个从 PrintJob 指向 Product 的关系。我需要一个相反的方向吗?
但我希望快到了!
编辑
没关系,我自己找到了最后一个。我需要将连接列名称设置为 productId 而不是 ProductId。固定的。谢谢大家:)
最佳答案
据我所知,您有 PrintJob::$product
字段和 PrintJob::$productId
字段。
您正在尝试使用 PrintJob
的显式 productId
“外键”字段在 PrintJob
和 Product
之间建立连接> 实体。
但这不是 ORM 的工作方式。您不需要 PrintJob::$productId
,Doctrine 将从 PrintJob::$product
字段创建适当的外部列(@JoinColumn 注释说的是:@ JoinColumn(name="ProductId", referencedColumnName="ProductId")
).因此,您应该通过 PrintJob->setProduct( $product)
.
关于php - 学说 2 : field cannot be null when saving entity - due to relationships?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8834891/