【发布时间】:2020-03-24 05:34:09
【问题描述】:
我的 Symfony2/Doctrine2 webapp 中有一个 User 实体。这个用户有一个属性last_updated 来标识最近的时间,一切都发生了变化。我在我的数据库中将此属性设置为NOT NULL。到目前为止,一切顺利。
我认为在数据库中创建一个 SQL 触发器是一种很好的做法,它将每个 INSERT 或 UPDATE 上的 last_updated 设置为 NOW()。所以你不必在你的应用程序中关心这个。这就是我所做的,我在我的数据库中实现了这个触发器。
但如果我现在在我的应用中创建一个用户
$user = new User();
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
我收到 Symfony 的错误消息:
执行
'INSERT INTO User (username, ..., last_updated) VALUES (?, ..., ?)'时发生异常 带参数["johndoe", ..., null]:SQLSTATE[23000]:违反完整性约束:1048 列
'last_updated'不能为空
问题很明显:Symfony 正在尝试使用参数 null 为 last_updated 向数据库触发 INSERT 语句,这是不允许的 - 因为此属性可能不为空。
我很快想到了两种解决方法:
- 一种解决方法是从实体描述中删除
last_updated字段。然后 Symfony 不会尝试为此列向数据库传递任何内容,触发器会设置适当的值。但我认为这不是一个好方法,因为一旦我尝试更新数据库架构 (doctrine:schema:update --force),我就会失去我的last_updated-column。 - 另一种解决方法:只需在
persist()和flush()之前执行$user->setLastUpdated(new \DateTime())。但这会最大限度地减少在我的数据库上使用触发器的优势,以避免在我的应用程序中关心它。
有什么方法可以让 Symfony/Doctrine 知道我的数据库上有一个触发器在运行?如果没有,(如何)我可以连接到 Symfony/Doctrine 以实施适当的解决方法?
【问题讨论】:
-
你可以阅读 Lifecycle Callbacks - symfony.com/doc/current/book/doctrine.html#lifecycle-callbacks,我认为它会很有用。
-
谢谢,好主意。所以 db 层上的触发器在这里不可用。
标签: symfony doctrine-orm triggers