Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Minor
-
Resolution: Unresolved
-
Affects Version/s: 2.3.1
-
Fix Version/s: None
-
Component/s: ORM
-
Security Level: All
-
Labels:None
Description
When creating a new Post and adding it to a collection in an existing Thread (i.e. loaded from the database), referencing Thread's posts collection in Post's @PostPersist callback returns the Post twice. To clarify, this only happens when Thread was previously persisted. If I'm creating a new Thread object the code works as expected. I've included some sample code to better illustrate my issue.
I don't know if this is a bug, or if I'm doing something that I shouldn't be, but I couldn't find this limitation mentioned in the documentation, and this seems to go against the expected behavior.
Here are my sample entities:
/** * @Entity * @Table(name="thread") */ class Thread { /** * @Id * @GeneratedValue * @Column(type="integer") */ protected $id; /** * @OneToMany(targetEntity="Post", mappedBy="thread", cascade={"persist", "remove"}) */ protected $posts; public function __construct() { $this->posts = new ArrayCollection(); } public function getPosts() { return $this->posts->toArray(); } public function addPost(Post $post) { $post->setThread($this); $this->posts->add($post); } } /** * @Entity * @Table(name="post") * @HasLifecycleCallbacks */ class Post { /** * @Id * @GeneratedValue * @Column(type="integer") */ protected $id; /** * @ManyToOne(targetEntity="Thread", inversedBy="posts") * @JoinColumn(name="thread_id", referencedColumnName="id") */ protected $thread; public function getId() { return $this->id; } /** * @PostPersist */ public function onPostPersist() { $posts = $this->thread->getPosts(); foreach ($posts as $post) { echo 'id: ' . $post->getId() . ' type: ' . get_class($alert) . '<br />'; } } public function setThread(Thread $thread) { $this->thread = $thread; } }
And the calling code:
// Grab an existing thread. $thread = $em->getReference('Thread', 1); $thread->addPost(new Post()); $em->flush();
This outputs:
id: 1 type: Post id: 1 type: Post
Alternatively:
// Create a new thread. $thread = new Thread() $thread->addPost(new Post()); $em->persist($thread); $em->flush();
This outputs:
id: 1 type: Post