DDC-4005: Persist incorrectly insert data to identity map #4890

Closed
opened 2026-01-22 14:51:33 +01:00 by admin · 3 comments
Owner

Originally created by @doctrinebot on GitHub (Nov 19, 2015).

Originally assigned to: @Ocramius on GitHub.

Jira issue originally created by user pk16011990:

ArticleAttribute has a composite primary key that contains association to Article that has generated primary key.
The example tries to persist ArticleAttribute without persisting and flushing Article first. Article does not have primary key yet and therefore when ArticleAttribute has incomplete primary key. The bad thing is that Doctrine instead of throwing exception inserts both ArticleAttribute entities into identity map under same hash (because AssignedGenerator created a hash containing NULL instead of Article's ID).

Doctrine\ORM\Id\AssignedGenerator returns same identifier for two diferent instances of ArticleAttribute.
Notice that $value in a67332fb51/lib/Doctrine/ORM/Id/AssignedGenerator.php (L58) can be NULL and therefore generated ID can contain NULL.

I would appreciate if Doctrine threw an exception in such situation instead of behaving as if everything was OK.

/****
 * @Entity
 */
class ArticleAttribute
{
    /*** @Id @ManyToOne(targetEntity="Article") **/
    private $article;

    /*** @Id @Column(type="string") **/
    private $attribute;

    /*** @Column(type="string") **/
    private $value;

    public function **construct($name, $value, $article) {
        $this->attribute = $name;
        $this->value = $value;
        $this->article = $article;
    }
}
/****
 * @Entity
 */
class Article
{
    /*** @Id @Column(type="integer") @GeneratedValue **/
    private $id;
    /*** @Column(type="string") **/
    private $title;
}
$em = EntityManager::create($params, $config);

$article = new Article();
$article2 = new Article();

$articleAttribute = new ArticleAttribute('foo', 'value', $article);
$articleAttribute2 = new ArticleAttribute('foo', 'value', $article2);

$em->persist($articleAttribute);
$em->persist($articleAttribute2);

var_dump($em->getUnitOfWork()->isInIdentityMap($articleAttribute)); //true
var_dump($em->getUnitOfWork()->isInIdentityMap($articleAttribute2)); //true
var*dump(in*array($articleAttribute, $em->getUnitOfWork()->getIdentityMap()[ArticleAttribute::class], true)); //true
var*dump(in*array($articleAttribute2, $em->getUnitOfWork()->getIdentityMap()[ArticleAttribute::class], true)); //false - expects true
Originally created by @doctrinebot on GitHub (Nov 19, 2015). Originally assigned to: @Ocramius on GitHub. Jira issue originally created by user pk16011990: ArticleAttribute has a composite primary key that contains association to Article that has generated primary key. The example tries to persist ArticleAttribute without persisting and flushing Article first. Article does not have primary key yet and therefore when ArticleAttribute has incomplete primary key. The bad thing is that Doctrine instead of throwing exception inserts both ArticleAttribute entities into identity map under same hash (because AssignedGenerator created a hash containing NULL instead of Article's ID). `Doctrine\ORM\Id\AssignedGenerator` returns same identifier for two diferent instances of ArticleAttribute. Notice that $value in https://github.com/doctrine/doctrine2/blob/a67332fb51e0572b3d8edba4ae6a1c9b979ac8fb/lib/Doctrine/ORM/Id/AssignedGenerator.php#L58 can be NULL and therefore generated ID can contain NULL. I would appreciate if Doctrine threw an exception in such situation instead of behaving as if everything was OK. ``` /**** * @Entity */ class ArticleAttribute { /*** @Id @ManyToOne(targetEntity="Article") **/ private $article; /*** @Id @Column(type="string") **/ private $attribute; /*** @Column(type="string") **/ private $value; public function **construct($name, $value, $article) { $this->attribute = $name; $this->value = $value; $this->article = $article; } } ``` ``` /**** * @Entity */ class Article { /*** @Id @Column(type="integer") @GeneratedValue **/ private $id; /*** @Column(type="string") **/ private $title; } ``` ``` $em = EntityManager::create($params, $config); $article = new Article(); $article2 = new Article(); $articleAttribute = new ArticleAttribute('foo', 'value', $article); $articleAttribute2 = new ArticleAttribute('foo', 'value', $article2); $em->persist($articleAttribute); $em->persist($articleAttribute2); var_dump($em->getUnitOfWork()->isInIdentityMap($articleAttribute)); //true var_dump($em->getUnitOfWork()->isInIdentityMap($articleAttribute2)); //true var*dump(in*array($articleAttribute, $em->getUnitOfWork()->getIdentityMap()[ArticleAttribute::class], true)); //true var*dump(in*array($articleAttribute2, $em->getUnitOfWork()->getIdentityMap()[ArticleAttribute::class], true)); //false - expects true ```
admin added the BugIncompleteMissing Tests labels 2026-01-22 14:51:33 +01:00
admin closed this issue 2026-01-22 14:51:33 +01:00
Author
Owner

@boris-brtan commented on GitHub (Aug 20, 2018):

Hi,
what is the status of this bug, is it somehow solved?

@boris-brtan commented on GitHub (Aug 20, 2018): Hi, what is the status of this bug, is it somehow solved?
Author
Owner

@Ocramius commented on GitHub (Aug 20, 2018):

Closing: requires a test case which is missing.

@Ocramius commented on GitHub (Aug 20, 2018): Closing: requires a test case which is missing.
Author
Owner

@boris-brtan commented on GitHub (Nov 15, 2018):

THX, we found some way by creating new packagist repo

@boris-brtan commented on GitHub (Nov 15, 2018): THX, we found some way by creating new packagist repo
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#4890