【问题标题】:Symfony 2 - Updating a table based on newly inserted record in another tableSymfony 2 - 根据另一个表中新插入的记录更新表
【发布时间】:2012-07-07 18:18:52
【问题描述】:

我正在尝试使用 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,希望它可以通过在我的 Topic.orm.yml 文件中添加 cascade: [ 'persist' ] 来解决问题,但它也没有帮助。

谁能指点我一个解决方案或一个示例类?

我的论坛主题是:

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 ]

我的论坛帖子是:

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

【问题讨论】:

  • 有趣的是:在我将映射信息转换为注释后,它就像魅力一样......

标签: symfony doctrine-orm


【解决方案1】:

我相信你让这件事变得更加困难,因为你认为你必须先刷新你的帖子,然后才能将它与你的主题相关联。

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( ) 方法,在其中添加 setLastPost 调用。

让关联的一方像这样照顾双方是相对常见的做法,以帮助保持良好的同步 - 请参阅Working with Associations

【讨论】:

  • 我已经尝试过后一种方法,但 Doctrine 似乎没有在 forum_topics 表上进行更新。我什至试过调用$em->persist($topic),但还是一样,没有效果。
  • 嗯,有趣 - 我知道有三种情况可能会导致: 1. 主题实体没有由 EntityManager 管理,因此它无法检测到更改(如果您获取来自数据库的主题,不太可能是这样) 2. 关联未正确映射(仅保留对关联拥有方的更改) 3. 主题实体配置了显式或通知更改跟踪 可以您使用两个模型的映射更新您的问题以帮助诊断?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2017-08-01
  • 2019-01-10
  • 1970-01-01
相关资源
最近更新 更多