doctrine / data-fixtures

Doctrine2 ORM Data Fixtures Extensions
http://www.doctrine-project.org
MIT License
2.77k stars 224 forks source link

Compound ids trip up the ProxyReferenceRepository #135

Open Seldaek opened 10 years ago

Seldaek commented 10 years ago

I have a class that has two identifier fields (a numeric id and a user ManyToOne) so that every user has their own sequence of numeric ids. This causes failures together with the liip functional test bundle when reloading a sqlite DB from cache I believe.

Here is a stack trace:

Array to string conversion

vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php:2899
vendor\doctrine\orm\lib\Doctrine\ORM\EntityManager.php:512
app\cache\test\jms_diextra\doctrine\EntityManager_531d8d621ddd2.php:240
vendor\doctrine\data-fixtures\lib\Doctrine\Common\DataFixtures\ProxyReferenceRepository.php:97
vendor\doctrine\data-fixtures\lib\Doctrine\Common\DataFixtures\ProxyReferenceRepository.php:123 vendor\liip\functional-test-bundle\Liip\FunctionalTestBundle\Test\WebTestCase.php:274

The ProxyReferenceRepository's serialize and unserialize methods don't deal with non-numeric ids it seems.

Relates to https://github.com/doctrine/data-fixtures/commit/8ffac1c63f34124f693b93889fa32f4036eb241b kinda.

If I dump the $proxyReference at line 91 it is like this:

array(2) {
  [0] =>
  string(32) "Entity\Object"
  [1] =>
  array(2) {
    'id' =>
    int(1)
    'parent' =>
    array(3) {
      '__initializer__' =>
      array(0) {
        ...
      }
      '__cloner__' =>
      array(0) {
        ...
      }
      '__isInitialized__' =>
      bool(false)
    }
  }
}

/cc @guilhermeblanco

cevou commented 9 years ago

Is there already a solution for this issue? I think it's a general problem if a field, which is part of the id, doesn't contain a simple type but a reference to another entity. During serialization the getIdentifier method calls getIdentifierValues on the class. Here only the proxy objects are returned and these objects are serialized. During this the real id of reference is lost. Maybe there could be a check if the identifiers array contains a Proxy instance like this:

if ( ! $uow->isInIdentityMap($reference)) {
    $class = $this->manager->getClassMetadata(get_class($reference));

    $values = $class->getIdentifierValues($reference);

    foreach ($values as $key => $value) {
        if($value instanceof Proxy) {
            $proxyIdentifier = $this->getIdentifier($value, $uow);
             //only a single id is accepted.
             $values[$key] = $proxyIdentifier[array_keys($proxyIdentifier)[0]];
        }
    }
    return $values;
}

This works for me.

JustBlackBird commented 7 years ago

Is there any progress on the issue?

vviippola commented 6 years ago

+1

paulinevos commented 6 years ago

+1, March 2018 and still having this problem. We can't use the ORM as intended now because tests fail upon loading fixtures.

Ocramius commented 6 years ago

@JustBlackBird @vviippola @paulinevos please help out on https://github.com/doctrine/data-fixtures/pull/167