Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UniqueValueResolver's deep_copy calls prevent relation resolving in entity managers #1084

Open
func0der opened this issue May 4, 2021 · 2 comments
Labels

Comments

@func0der
Copy link

func0der commented May 4, 2021

Hey there,

I think I came to the right place for this, though my usecase might be doctrine-specific.

Given the following fixture set:

Main\V1\Entity\Permission:
    permission_text:
        name: 'text'
    permission_email:
        name: 'email'
    permission_user:
        name: 'user'
    permission_admin:
        name: 'admin'

Main\V1\Entity\User:
    user_random:
        username: 'random'
        permissions (unique): 3x @permission_*

And the following tables in the database:

CREATE TABLE `permission` (
  `permission_id` int(11) NOT NULL AUTO_INCREMENT,
  `permission_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE TABLE `user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `user_username` (`user_username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE TABLE `userpermission` (
  `userpermission_user_id` int(11) NOT NULL,
  `userpermission_permission_id` int(11) NOT NULL,
  PRIMARY KEY (`userpermission_user_id`,`userpermission_permission_id`),
  KEY `IDX_AD35BE53A4C53F09` (`userpermission_user_id`),
  KEY `IDX_AD35BE53E175D071` (`userpermission_permission_id`),
  CONSTRAINT `FK_AD35BE53A4C53F09` FOREIGN KEY (`userpermission_user_id`) REFERENCES `user` (`user_id`),
  CONSTRAINT `FK_AD35BE53E175D071` FOREIGN KEY (`userpermission_permission_id`) REFERENCES `permission` (`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

We see that that userpermission has primary key that consists of the two foreign keys combined.
This means that the combination of those two is meant to be unique.
This is why, I can not simply write permissions: 3x @permission_* in the Main\V1\Entity\User fixture, but need to have unique values for this case.

When I am using unique here, which I know make the fixture unique across the whole fixture set, the database table permission will contain the four entries from the Main\V1\Entity\Permission fixture AND as duplicates the three that are used in the Main\V1\Entity\User fixture's line: permissions (unique): 3x @permission_*.

I know from Doctrine that is store references to managed objects by the spl_object_hash of objects. Since the \Nelmio\Alice\Definition\Value\UniqueValue deep_clones the object, a new object is created which therefor has another spl_object_hash, which messes up the reference.
By the way: \Nelmio\Alice\Definition\Value\UniqueValue does this in the __constructor and in getValue(). Shouldn't one time be enough? 🤔

I would figure that this, if not intended, does not play well with other entity mangers as well.

Is this intended behavior?

And if so, how would you go about to have an isolated unique case. (i know, this is a question not a bug report and kinda off-topic).

@theofidry
Copy link
Member

I know from Doctrine that is store references to managed objects by the spl_object_hash of objects. Since the \Nelmio\Alice\Definition\Value\UniqueValue deep_clones the object, a new object is created which therefor has another spl_object_hash, which messes up the reference.

I do not think this should be an issue as alice there takes fixtures and outputs objects, although there might be deep cloning within those objects should not be known by Doctrine yet. Or do you mean this is happening for injected objects?

@func0der
Copy link
Author

If by "injcted objects" you mean those, you can add additionally to the ones created from fixtures files, no.

The fact that Doctrine does not know about the objects at that point in time, does not matter for this issue.

The object generated for permission_text has for example the the object hash 1234.
If that fixture object is chosen by the user_random fixture, it is cloned by UniqueValue, which changes its object hash to abcd.
So the objects might be equal but not the same, which will is a problem for the entity managers (e.g. Doctrine).

I hope this shows what the problem is.

@theofidry theofidry added the Bug label May 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants