2017-10-17 153 views
0

我有一个由Zend\Form数据自动补水而创建的复杂/嵌套对象。现在我想用Doctrine 2保存它。最好的情况是在顶层调用一个persist(...)和一个flush(...)。但它不这样工作。所以现在我有以下问题:如何仅在实体不存在的情况下仅保留一个关系的一端,而另一端仅保留一个关系?

有对象UserOrder。关系是1:n(所以,1UsernOrder s)。 User已经存在。当UserJoe试图保存的多于一个Order(例如它的第二顺序),将发生错误:

一个新的实体是通过中没有配置于以下关系'... \订单#用户发现对实体级联持久化操作:... \ User @ 000000003ba4559d000000005be8d831。解决此问题:显式调用此未知实体上的EntityManager#persist()或配置级联将该关联保存在映射中,例如@ManyToOne(..,cascade = {“persist”})。如果你找不到哪个实体导致问题实现'... \ User #__ toString()'以获得线索。

还好吧,我加cascade={"persist"}(尽管它没有意义在这里,但无论如何,只是尝试一下):

class Order 
{ 
    ... 
    /** 
    * @var User 
    * 
    * @ORM\ManyToOne(targetEntity="User", cascade={"persist"}) 
    */ 
    protected $user; 
    ... 
} 

现在它的工作原理,如果给定User不存在:创建了OrderUser

但如果User存在,出现错误:在执行 '(?,?,?,)INSERT INTO用户(用户名,角色,创建,更新)VALUES' 有发生

例外PARAMS [ “名为myUsername”, “成员”,NULL,NULL]:

SQLSTATE [23000]:完整性约束冲突:关键1062重复条目“名为myUsername 'username_UNIQUE'

如何处理萨维那么,那么User只会被保存,如果它不存在?

+0

你验证用symfony形式(或仅验证组件)这个对象?看一看[UniqueEntity Constraints](https:// symfony。com/doc/current/reference/constraints/UniqueEntity.html) – Matteo

+0

感谢您的评论,但我使用的是Zend \ Form,而不是Symfony。为了验证表单,我使用了Zend验证功能。 – automatix

+0

几乎每次遇到Doctrine错误“通过关系'... Order#user'发现了一个新实体,该实体没有被配置为级联实体的持久化操作”我发现我做了一些错误的事情,通常是小。 用英语说,错误告诉你订单已被保留,但与其关联的用户没有被保存。这意味着被分配的用户不会被Doctrine知道为数据库中的实体。仔细检查你的代码,确认你实际上是分配一个合适的用户并且它是一个有效的用户。 – MEmerson

回答

0

解决的办法是在保存引用实体之前坚持User。如果它不存在,它需要创建(persist ED和ED flush)第一:

$user = $this->entityManager->getRepository(User::class)->findOneBy(
    ['username' => $dataObject->getUser()->getUsername()] 
); 
if (! $user) { 
    $this->entityManager->persist($dataObject->getUser()); 
    $this->entityManager->flush($dataObject->getUser()); 
    $user = $this->entityManager->getRepository(User::class)->findOneBy(
     ['username' => $dataObject->getUser()->getUsername()] 
    ); 
} 
$dataObject->setUser($user); 

$this->entityManager->persist($dataObject); 
$this->entityManager->flush(); 

而且cascade={"persist"}不应该使用,因为它实际上并没有在这种情况下才有意义。


编辑

或者更简单:

$user = $this->entityManager->getRepository(User::class)->findOneBy(
    ['username' => $dataObject->getUser()->getUsername()] 
); 
if ($user) { 
    $dataObject->setUser($user); 
} else { 
    $this->entityManager->persist($dataObject->getUser()); 
} 

$this->entityManager->persist($dataObject); 
$this->entityManager->flush(); 
相关问题