我们的项目中存在一个奇怪的问题,其中某些教义实体没有被保存。该问题并非每次都发生,而是间歇性发生,我们也不知道是什么原因引起的。
我们保存了两个链接的实体:
$one = (new One)
->setValues()
...
;
$two = (new Two)
->setOne($one)
->setUser($user)
;
$em->persist($one);
$em->persist($two);
$em->flush();
关系/实体定义如下:
class User {
...
/**
* @var Two[]|Collection
* @ORM\OneToMany(targetEntity="Two", mappedBy="user")
*/
private $twos;
...
}
class One {
...
/**
* @var Two[]|Collection
* @ORM\OneToMany(targetEntity="Two", mappedBy="one")
*/
private $twos;
...
}
Class Two {
...
/**
* Note this field in the db is an auto-increment
* @ORM\Column(name="two_id", type="integer")
*/
private $id;
/**
* @var One
* @ORM\Id()
* @ORM\ManyToOne(targetEntity="One", inversedBy="twos")
* @ORM\JoinColumn(name="one_id", referencedColumnName="one_id")
*/
private $one;
/**
* @var User
* @ORM\Id()
* @ORM\ManyToOne(targetEntity="User", inversedBy="twos")
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
*/
private $user;
...
}
我们没有看到任何错误,并且当在DBAL中启用调试日志记录时,我们可以看到事务开始,所有插入(包括
Two
)和提交的日志条目。我们无法在本地重现该问题,因此无法使用步进调试器来解决该问题。大多数情况下,两个实体都会保存,但并非每次都保存。如果我们从ObjectManager中清除
Two
实体并尝试从数据库中重新加载它,则表明它确实具有ID。$em->clear(Two::class);
$two = $twoRepository->findTwo($user, $one);
if ($two) {
$logger->info('Two created', ['two' => $two->getId(),]);
}
现在,当出现
Two
未被保存的情况时,我们可以看到一个日志,该日志正在输出一个id,但是当我们检查相关的db表时,其中没有包含该id的行。任何时候都不会引发异常,并且我们看不到任何其他可能表明有问题的日志。
我们不知道会发生什么。为实体提供自动增量但未保存的事实表明,db事务中可能存在问题。但是,据我了解,该事务将在对
flush()
的调用内发生,并且没有迹象表明该事务必须回滚。再加上随后的从数据库重新加载实体的调用发生在那之后,因此Doctrine必须从数据库或从其内部对象存储中检索该实体(尽管人们很清楚clear()
应该意味着它必须返回到db以加载该实体)。 最佳答案
错误的警报。事实证明,我们的系统允许用户从UI中删除实体Two
(但不能删除实体One
)。该网站的流量相当大,并且在最初创建实体后不久,一群用户就在这样做,这使得看上去好像根本没有创建实体。
关于php - 教义实体未保存,但具有自动递增的ID,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59825029/