我正在尝试使用Symfony 2和Doctrine 2创建一个小型论坛应用程序。我的ForumTopic实体有一个last_post字段(oneToOne映射)。现在当我用
坚持我的新帖子时$em->persist($post);
我想更新我的ForumTopic实体,以使其last_post字段引用此新帖子。我刚刚意识到使用Doctrine postPersist Listener无法做到这一点,所以我决定使用一个小黑客,然后尝试:
$em->persist($post);
$em->flush();
$topic->setLastPost($post);
$em->persist($post);
$em->flush();
但它似乎没有更新我的主题表。
我还看了http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/working-with-associations.html#transitive-persistence-cascade-operations希望它能解决问题,方法是将cascade:['persist']添加到我的Topic.orm.yml文件中,但它也无济于事。
有人能指出我的解决方案或示例类吗?
我的论坛是:
FrontBundle\Entity\ForumTopic:
type: entity
table: forum_topics
id:
id:
type: integer
generator:
strategy: AUTO
fields:
title:
type: string(100)
nullable: false
slug:
type: string(100)
nullable: false
created_at:
type: datetime
nullable: false
updated_at:
type: datetime
nullable: true
update_reason:
type: text
nullable: true
oneToMany:
posts:
targetEntity: ForumPost
mappedBy: topic
manyToOne:
created_by:
targetEntity: User
inversedBy: articles
nullable: false
updated_by:
targetEntity: User
nullable: true
default: null
topic_group:
targetEntity: ForumTopicGroup
inversedBy: topics
nullable: false
oneToOne:
last_post:
targetEntity: ForumPost
nullable: true
default: null
cascade: [ persist ]
uniqueConstraint:
uniqueSlugByGroup:
columns: [ topic_group, slug ]
我的ForumPost是:
FrontBundle\Entity\ForumPost:
type: entity
table: forum_posts
id:
id:
type: integer
generator:
strategy: AUTO
fields:
created_at:
type: datetime
nullable: false
updated_at:
type: datetime
nullable: true
update_reason:
type: string
nullable: true
text:
type: text
nullable: false
manyToOne:
created_by:
targetEntity: User
inversedBy: forum_posts
nullable: false
updated_by:
targetEntity: User
nullable: true
default: null
topic:
targetEntity: ForumTopic
inversedBy: posts
答案 0 :(得分:0)
我相信你让自己变得更加困难,因为你认为你必须先刷新你的帖子,然后再将它设置为关于你主题的关联。
Doctrine非常聪明,如果你坚持一个实体并将其设置为一个关联而没有先调用flush,它会确保当你调用flush时,它会先保留该实体,这样它就有一个ID可以与协会一起使用。
这意味着您真正需要做的就是:
// Assume that topic has been fetched from the DB, and post is completely new
$topic = $em->find('TopicModel', $topicId);
$post = new ForumPost();
// Fill in the post info
// Set up the association
$topic->setLastPost($post);
// And finally, persist and flush - no more effort needed
$em->persist($post);
$em->flush();
这样做的好处是你可以简单地使用prePersist事件监听器来更新帖子的最后一篇文章 - Doctrine将为你处理其他一切。
或者,如果你想要一种逻辑上更容易理解的方法,你可以自己让Post模型调用setLastPost - 例如,如果你在构造函数或setTopic中设置post的主题( )方法,在那里添加setLastPost调用。
让一个协会的一方照顾这样的双方是相对常见的做法,以帮助保持良好的同步 - 见Working with Associations。