diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 1336a57f3..fbbab7b6a 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -19,36 +19,33 @@ namespace Doctrine\ORM; -use Doctrine\Common\Persistence\Mapping\RuntimeReflectionService; -use Doctrine\DBAL\LockMode; -use Doctrine\ORM\Internal\HydrationCompleteHandler; -use Doctrine\ORM\Mapping\Reflection\ReflectionPropertiesGetter; -use Exception; -use InvalidArgumentException; -use UnexpectedValueException; - use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\Common\NotifyPropertyChanged; -use Doctrine\Common\PropertyChangedListener; +use Doctrine\Common\Persistence\Mapping\RuntimeReflectionService; use Doctrine\Common\Persistence\ObjectManagerAware; -use Doctrine\ORM\Mapping\ClassMetadata; -use Doctrine\ORM\Proxy\Proxy; - +use Doctrine\Common\PropertyChangedListener; +use Doctrine\DBAL\LockMode; +use Doctrine\ORM\Cache\Persister\CachedPersister; use Doctrine\ORM\Event\LifecycleEventArgs; -use Doctrine\ORM\Event\PreUpdateEventArgs; -use Doctrine\ORM\Event\PreFlushEventArgs; +use Doctrine\ORM\Event\ListenersInvoker; use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Event\PostFlushEventArgs; -use Doctrine\ORM\Event\ListenersInvoker; - -use Doctrine\ORM\Cache\Persister\CachedPersister; -use Doctrine\ORM\Persisters\Entity\BasicEntityPersister; -use Doctrine\ORM\Persisters\Entity\SingleTablePersister; -use Doctrine\ORM\Persisters\Entity\JoinedSubclassPersister; -use Doctrine\ORM\Persisters\Collection\OneToManyPersister; +use Doctrine\ORM\Event\PreFlushEventArgs; +use Doctrine\ORM\Event\PreUpdateEventArgs; +use Doctrine\ORM\Internal\HydrationCompleteHandler; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\Reflection\ReflectionPropertiesGetter; use Doctrine\ORM\Persisters\Collection\ManyToManyPersister; +use Doctrine\ORM\Persisters\Collection\OneToManyPersister; +use Doctrine\ORM\Persisters\Entity\BasicEntityPersister; +use Doctrine\ORM\Persisters\Entity\JoinedSubclassPersister; +use Doctrine\ORM\Persisters\Entity\SingleTablePersister; +use Doctrine\ORM\Proxy\Proxy; use Doctrine\ORM\Utility\IdentifierFlattener; +use Exception; +use InvalidArgumentException; +use UnexpectedValueException; /** * The UnitOfWork is responsible for tracking changes to objects during an @@ -890,7 +887,7 @@ class UnitOfWork implements PropertyChangedListener $idValue = $idGen->generate($this->em, $entity); if ( ! $idGen instanceof \Doctrine\ORM\Id\AssignedGenerator) { - $idValue = array($class->identifier[0] => $idValue); + $idValue = [$class->getSingleIdentifierFieldName() => $this->convertSingleFieldIdentifierToPHPValue($class, $idValue)]; $class->setIdentifierValues($entity, $idValue); } @@ -1008,16 +1005,17 @@ class UnitOfWork implements PropertyChangedListener if ($postInsertIds) { // Persister returned post-insert IDs foreach ($postInsertIds as $postInsertId) { - $id = $postInsertId['generatedId']; + $idField = $class->getSingleIdentifierFieldName(); + $idValue = $this->convertSingleFieldIdentifierToPHPValue($class, $postInsertId['generatedId']); + $entity = $postInsertId['entity']; $oid = spl_object_hash($entity); - $idField = $class->identifier[0]; - $class->reflFields[$idField]->setValue($entity, $id); + $class->reflFields[$idField]->setValue($entity, $idValue); - $this->entityIdentifiers[$oid] = array($idField => $id); + $this->entityIdentifiers[$oid] = array($idField => $idValue); $this->entityStates[$oid] = self::STATE_MANAGED; - $this->originalEntityData[$oid][$idField] = $id; + $this->originalEntityData[$oid][$idField] = $idValue; $this->addToIdentityMap($entity); } @@ -3467,4 +3465,20 @@ class UnitOfWork implements PropertyChangedListener } } } + + /** + * @param ClassMetadata $class + * @param mixed $identifierValue + * + * @return mixed the identifier after type conversion + * + * @throws \Doctrine\ORM\Mapping\MappingException if the entity has more than a single identifier + */ + private function convertSingleFieldIdentifierToPHPValue(ClassMetadata $class, $identifierValue) + { + return $this->em->getConnection()->convertToPHPValue( + $identifierValue, + $class->getTypeOfField($class->getSingleIdentifierFieldName()) + ); + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC5684Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC5684Test.php new file mode 100644 index 000000000..a25178de2 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC5684Test.php @@ -0,0 +1,117 @@ +_schemaTool->createSchema([$this->_em->getClassMetadata(DDC5684Object::CLASSNAME)]); + } + + protected function tearDown() + { + $this->_schemaTool->dropSchema([$this->_em->getClassMetadata(DDC5684Object::CLASSNAME)]); + + parent::tearDown(); + } + + public function testAutoIncrementIdWithCustomType() + { + $object = new DDC5684Object(); + $this->_em->persist($object); + $this->_em->flush(); + + $this->assertInstanceOf(DDC5684ObjectId::CLASSNAME, $object->id); + } + + public function testFetchObjectWithAutoIncrementedCustomType() + { + $object = new DDC5684Object(); + $this->_em->persist($object); + $this->_em->flush(); + $this->_em->clear(); + + $rawId = $object->id->value; + $object = $this->_em->find(DDC5684Object::CLASSNAME, new DDC5684ObjectId($rawId)); + + $this->assertInstanceOf(DDC5684ObjectId::CLASSNAME, $object->id); + $this->assertEquals($rawId, $object->id->value); + } +} + +class DDC5684ObjectIdType extends DBALTypes\IntegerType +{ + const CLASSNAME = __CLASS__; + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return new DDC5684ObjectId($value); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return $value->value; + } + + public function getName() + { + return self::CLASSNAME; + } + + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} + +class DDC5684ObjectId +{ + const CLASSNAME = __CLASS__; + + public $value; + + public function __construct($value) + { + $this->value = $value; + } + + public function __toString() + { + return (string) $this->value; + } +} + +/** + * @Entity + * @Table(name="ticket_5684_objects") + */ +class DDC5684Object +{ + const CLASSNAME = __CLASS__; + + /** + * @Id + * @Column(type=Doctrine\Tests\ORM\Functional\Ticket\DDC5684ObjectIdType::class) + * @GeneratedValue(strategy="AUTO") + */ + public $id; +}