1
0
mirror of synced 2025-01-29 19:41:45 +03:00

Removing usage of ClassUtil where not strictly needed

Optimizing the ClassMetadataFactory API instead and using ClassMetadata to check actual class names as da962f2e and c27b4de0 introduced too much overhead
This commit is contained in:
Marco Pivetta 2012-04-01 16:27:31 +02:00
parent 85ea27dba2
commit cb7a77cc03
6 changed files with 69 additions and 72 deletions

View File

@ -22,7 +22,6 @@ namespace Doctrine\ORM\Id;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\ORMException; use Doctrine\ORM\ORMException;
use Doctrine\Common\Util\ClassUtils;
/** /**
* Special generator for application-assigned identifiers (doesnt really generate anything). * Special generator for application-assigned identifiers (doesnt really generate anything).
@ -44,7 +43,7 @@ class AssignedGenerator extends AbstractIdGenerator
*/ */
public function generate(EntityManager $em, $entity) public function generate(EntityManager $em, $entity)
{ {
$class = $em->getClassMetadata(ClassUtils::getClass($entity)); $class = $em->getClassMetadata(get_class($entity));
$idFields = $class->getIdentifierFieldNames(); $idFields = $class->getIdentifierFieldNames();
$identifier = array(); $identifier = array();

View File

@ -155,43 +155,44 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
*/ */
public function getMetadataFor($className) public function getMetadataFor($className)
{ {
if ( ! isset($this->loadedMetadata[$className])) { if (isset($this->loadedMetadata[$className])) {
$realClassName = $className; return $this->loadedMetadata[$className];
}
// Check for namespace alias $realClassName = $className;
if (strpos($className, ':') !== false) {
list($namespaceAlias, $simpleClassName) = explode(':', $className);
$realClassName = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
if (isset($this->loadedMetadata[$realClassName])) { // Check for namespace alias
// We do not have the alias name in the map, include it if (strpos($className, ':') !== false) {
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; list($namespaceAlias, $simpleClassName) = explode(':', $className);
$realClassName = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
} else {
$realClassName = ClassUtils::getRealClass($realClassName);
}
return $this->loadedMetadata[$realClassName]; if (isset($this->loadedMetadata[$realClassName])) {
} // We do not have the alias name in the map, include it
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
return $this->loadedMetadata[$realClassName];
}
if ($this->cacheDriver) {
if (($cached = $this->cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) {
$this->wakeupReflection($cached, $this->getReflectionService());
$this->loadedMetadata[$realClassName] = $cached;
} else { } else {
$realClassName = ClassUtils::getRealClass($realClassName); foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
} $this->cacheDriver->save(
"$loadedClassName\$CLASSMETADATA", $this->loadedMetadata[$loadedClassName], null
if ($this->cacheDriver) { );
if (($cached = $this->cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) {
$this->wakeupReflection($cached, $this->getReflectionService());
$this->loadedMetadata[$realClassName] = $cached;
} else {
foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
$this->cacheDriver->save(
"$loadedClassName\$CLASSMETADATA", $this->loadedMetadata[$loadedClassName], null
);
}
} }
} else {
$this->loadMetadata($realClassName);
} }
} else {
$this->loadMetadata($realClassName);
}
if ($className != $realClassName) { if ($className != $realClassName) {
// We do not have the alias name in the map, include it // We do not have the alias name in the map, include it
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
}
} }
return $this->loadedMetadata[$className]; return $this->loadedMetadata[$className];

View File

@ -22,8 +22,7 @@ namespace Doctrine\ORM;
use Doctrine\ORM\Mapping\ClassMetadata, use Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\Common\Collections\Collection, Doctrine\Common\Collections\Collection,
Doctrine\Common\Collections\ArrayCollection, Doctrine\Common\Collections\ArrayCollection,
Closure, Closure;
Doctrine\Common\Util\ClassUtils;
/** /**
* A PersistentCollection represents a collection of elements that have persistent state. * A PersistentCollection represents a collection of elements that have persistent state.
@ -307,7 +306,7 @@ final class PersistentCollection implements Collection
$this->association['isOwningSide'] && $this->association['isOwningSide'] &&
$this->association['type'] === ClassMetadata::MANY_TO_MANY && $this->association['type'] === ClassMetadata::MANY_TO_MANY &&
$this->owner && $this->owner &&
$this->em->getClassMetadata(ClassUtils::getClass($this->owner))->isChangeTrackingNotify()) { $this->em->getClassMetadata(get_class($this->owner))->isChangeTrackingNotify()) {
$this->em->getUnitOfWork()->scheduleForDirtyCheck($this->owner); $this->em->getUnitOfWork()->scheduleForDirtyCheck($this->owner);
} }
} }

View File

@ -1504,7 +1504,7 @@ class BasicEntityPersister
if ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) { if ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) {
$idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value); $idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
} else { } else {
$class = $this->_em->getClassMetadata(ClassUtils::getClass($value)); $class = $this->_em->getClassMetadata(get_class($value));
$idValues = $class->getIdentifierValues($value); $idValues = $class->getIdentifierValues($value);
} }

View File

@ -23,8 +23,7 @@ namespace Doctrine\ORM\Persisters;
use Doctrine\ORM\Mapping\ClassMetadata, use Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\PersistentCollection, Doctrine\ORM\PersistentCollection,
Doctrine\ORM\UnitOfWork, Doctrine\ORM\UnitOfWork;
Doctrine\Common\Util\ClassUtils;
/** /**
* Persister for many-to-many collections. * Persister for many-to-many collections.
@ -44,7 +43,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
protected function _getDeleteRowSQL(PersistentCollection $coll) protected function _getDeleteRowSQL(PersistentCollection $coll)
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$class = $this->_em->getClassMetadata(ClassUtils::getClass($coll->getOwner())); $class = $this->_em->getClassMetadata(get_class($coll->getOwner()));
return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()) return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform())
. ' WHERE ' . implode(' = ? AND ', $mapping['joinTableColumns']) . ' = ?'; . ' WHERE ' . implode(' = ? AND ', $mapping['joinTableColumns']) . ' = ?';
@ -81,7 +80,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$columns = $mapping['joinTableColumns']; $columns = $mapping['joinTableColumns'];
$class = $this->_em->getClassMetadata(ClassUtils::getClass($coll->getOwner())); $class = $this->_em->getClassMetadata(get_class($coll->getOwner()));
$joinTable = $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()); $joinTable = $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform());
@ -119,7 +118,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
$identifier2 = $this->_uow->getEntityIdentifier($element); $identifier2 = $this->_uow->getEntityIdentifier($element);
if ($isComposite) { if ($isComposite) {
$class1 = $this->_em->getClassMetadata(ClassUtils::getClass($coll->getOwner())); $class1 = $this->_em->getClassMetadata(get_class($coll->getOwner()));
$class2 = $coll->getTypeClass(); $class2 = $coll->getTypeClass();
} }
@ -151,7 +150,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
*/ */
protected function _getDeleteSQL(PersistentCollection $coll) protected function _getDeleteSQL(PersistentCollection $coll)
{ {
$class = $this->_em->getClassMetadata(ClassUtils::getClass($coll->getOwner())); $class = $this->_em->getClassMetadata(get_class($coll->getOwner()));
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()) return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform())
@ -179,7 +178,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
} }
// Composite identifier // Composite identifier
$sourceClass = $this->_em->getClassMetadata(ClassUtils::getClass($mapping->getOwner())); $sourceClass = $this->_em->getClassMetadata(get_class($mapping->getOwner()));
foreach ($mapping['relationToSourceKeyColumns'] as $srcColumn) { foreach ($mapping['relationToSourceKeyColumns'] as $srcColumn) {
$params[] = $identifier[$sourceClass->fieldNames[$srcColumn]]; $params[] = $identifier[$sourceClass->fieldNames[$srcColumn]];

View File

@ -27,8 +27,7 @@ use Exception, InvalidArgumentException, UnexpectedValueException,
Doctrine\Common\Persistence\ObjectManagerAware, Doctrine\Common\Persistence\ObjectManagerAware,
Doctrine\ORM\Event\LifecycleEventArgs, Doctrine\ORM\Event\LifecycleEventArgs,
Doctrine\ORM\Mapping\ClassMetadata, Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Proxy\Proxy, Doctrine\ORM\Proxy\Proxy;
Doctrine\Common\Util\ClassUtils;
/** /**
* The UnitOfWork is responsible for tracking changes to objects during an * The UnitOfWork is responsible for tracking changes to objects during an
@ -376,7 +375,7 @@ class UnitOfWork implements PropertyChangedListener
private function computeScheduleInsertsChangeSets() private function computeScheduleInsertsChangeSets()
{ {
foreach ($this->entityInsertions as $entity) { foreach ($this->entityInsertions as $entity) {
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$this->computeChangeSet($class, $entity); $this->computeChangeSet($class, $entity);
} }
@ -399,7 +398,7 @@ class UnitOfWork implements PropertyChangedListener
throw new \InvalidArgumentException("Entity has to be managed for single computation " . self::objToStr($entity)); throw new \InvalidArgumentException("Entity has to be managed for single computation " . self::objToStr($entity));
} }
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
if ($class->isChangeTrackingDeferredImplicit()) { if ($class->isChangeTrackingDeferredImplicit()) {
$this->persist($entity); $this->persist($entity);
@ -434,7 +433,7 @@ class UnitOfWork implements PropertyChangedListener
list ($entity, $changeset) = $update; list ($entity, $changeset) = $update;
$this->entityChangeSets[$oid] = $changeset; $this->entityChangeSets[$oid] = $changeset;
$this->getEntityPersister(ClassUtils::getClass($entity))->update($entity); $this->getEntityPersister(get_class($entity))->update($entity);
} }
} }
@ -493,7 +492,7 @@ class UnitOfWork implements PropertyChangedListener
} }
if ( ! $class->isInheritanceTypeNone()) { if ( ! $class->isInheritanceTypeNone()) {
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
} }
// Fire PreFlush lifecycle callbacks // Fire PreFlush lifecycle callbacks
@ -839,7 +838,7 @@ class UnitOfWork implements PropertyChangedListener
} }
if ( ! $class->isInheritanceTypeNone()) { if ( ! $class->isInheritanceTypeNone()) {
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
} }
$actualData = array(); $actualData = array();
@ -887,7 +886,7 @@ class UnitOfWork implements PropertyChangedListener
$hasListeners = $this->evm->hasListeners(Events::postPersist); $hasListeners = $this->evm->hasListeners(Events::postPersist);
foreach ($this->entityInsertions as $oid => $entity) { foreach ($this->entityInsertions as $oid => $entity) {
if (ClassUtils::getClass($entity) !== $className) { if ($this->em->getClassMetadata(get_class($entity))->name !== $className) {
continue; continue;
} }
@ -946,7 +945,7 @@ class UnitOfWork implements PropertyChangedListener
$hasPostUpdateListeners = $this->evm->hasListeners(Events::postUpdate); $hasPostUpdateListeners = $this->evm->hasListeners(Events::postUpdate);
foreach ($this->entityUpdates as $oid => $entity) { foreach ($this->entityUpdates as $oid => $entity) {
if (ClassUtils::getClass($entity) !== $className) { if ($this->em->getClassMetadata(get_class($entity))->name !== $className) {
continue; continue;
} }
@ -993,7 +992,7 @@ class UnitOfWork implements PropertyChangedListener
$hasListeners = $this->evm->hasListeners(Events::postRemove); $hasListeners = $this->evm->hasListeners(Events::postRemove);
foreach ($this->entityDeletions as $oid => $entity) { foreach ($this->entityDeletions as $oid => $entity) {
if (ClassUtils::getClass($entity) !== $className) { if ($this->em->getClassMetadata(get_class($entity))->name !== $className) {
continue; continue;
} }
@ -1044,7 +1043,7 @@ class UnitOfWork implements PropertyChangedListener
$newNodes = array(); $newNodes = array();
foreach ($entityChangeSet as $entity) { foreach ($entityChangeSet as $entity) {
$className = ClassUtils::getClass($entity); $className = $this->em->getClassMetadata(get_class($entity))->name;
if ($calc->hasClass($className)) { if ($calc->hasClass($className)) {
continue; continue;
@ -1207,7 +1206,7 @@ class UnitOfWork implements PropertyChangedListener
*/ */
public function isScheduledForDirtyCheck($entity) public function isScheduledForDirtyCheck($entity)
{ {
$rootEntityName = $this->em->getClassMetadata(ClassUtils::getClass($entity))->rootEntityName; $rootEntityName = $this->em->getClassMetadata(get_class($entity))->rootEntityName;
return isset($this->scheduledForDirtyCheck[$rootEntityName][spl_object_hash($entity)]); return isset($this->scheduledForDirtyCheck[$rootEntityName][spl_object_hash($entity)]);
} }
@ -1288,7 +1287,7 @@ class UnitOfWork implements PropertyChangedListener
*/ */
public function addToIdentityMap($entity) public function addToIdentityMap($entity)
{ {
$classMetadata = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $classMetadata = $this->em->getClassMetadata(get_class($entity));
$idHash = implode(' ', $this->entityIdentifiers[spl_object_hash($entity)]); $idHash = implode(' ', $this->entityIdentifiers[spl_object_hash($entity)]);
if ($idHash === '') { if ($idHash === '') {
@ -1336,7 +1335,7 @@ class UnitOfWork implements PropertyChangedListener
// Note that you can not remember the NEW or DETACHED state in _entityStates since // Note that you can not remember the NEW or DETACHED state in _entityStates since
// the UoW does not hold references to such objects and the object hash can be reused. // the UoW does not hold references to such objects and the object hash can be reused.
// More generally because the state may "change" between NEW/DETACHED without the UoW being aware of it. // More generally because the state may "change" between NEW/DETACHED without the UoW being aware of it.
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$id = $class->getIdentifierValues($entity); $id = $class->getIdentifierValues($entity);
if ( ! $id) { if ( ! $id) {
@ -1398,7 +1397,7 @@ class UnitOfWork implements PropertyChangedListener
public function removeFromIdentityMap($entity) public function removeFromIdentityMap($entity)
{ {
$oid = spl_object_hash($entity); $oid = spl_object_hash($entity);
$classMetadata = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $classMetadata = $this->em->getClassMetadata(get_class($entity));
$idHash = implode(' ', $this->entityIdentifiers[$oid]); $idHash = implode(' ', $this->entityIdentifiers[$oid]);
if ($idHash === '') { if ($idHash === '') {
@ -1466,7 +1465,7 @@ class UnitOfWork implements PropertyChangedListener
return false; return false;
} }
$classMetadata = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $classMetadata = $this->em->getClassMetadata(get_class($entity));
$idHash = implode(' ', $this->entityIdentifiers[$oid]); $idHash = implode(' ', $this->entityIdentifiers[$oid]);
if ($idHash === '') { if ($idHash === '') {
@ -1521,7 +1520,7 @@ class UnitOfWork implements PropertyChangedListener
$visited[$oid] = $entity; // Mark visited $visited[$oid] = $entity; // Mark visited
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
// We assume NEW, so DETACHED entities result in an exception on flush (constraint violation). // We assume NEW, so DETACHED entities result in an exception on flush (constraint violation).
// If we would detect DETACHED here we would throw an exception anyway with the same // If we would detect DETACHED here we would throw an exception anyway with the same
@ -1595,7 +1594,7 @@ class UnitOfWork implements PropertyChangedListener
// can cause problems when a lazy proxy has to be initialized for the cascade operation. // can cause problems when a lazy proxy has to be initialized for the cascade operation.
$this->cascadeRemove($entity, $visited); $this->cascadeRemove($entity, $visited);
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$entityState = $this->getEntityState($entity); $entityState = $this->getEntityState($entity);
switch ($entityState) { switch ($entityState) {
@ -1661,7 +1660,7 @@ class UnitOfWork implements PropertyChangedListener
$visited[$oid] = $entity; // mark visited $visited[$oid] = $entity; // mark visited
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
// First we assume DETACHED, although it can still be NEW but we can avoid // First we assume DETACHED, although it can still be NEW but we can avoid
// an extra db-roundtrip this way. If it is not MANAGED but has an identity, // an extra db-roundtrip this way. If it is not MANAGED but has an identity,
@ -1815,7 +1814,7 @@ class UnitOfWork implements PropertyChangedListener
if ($prevManagedCopy !== null) { if ($prevManagedCopy !== null) {
$assocField = $assoc['fieldName']; $assocField = $assoc['fieldName'];
$prevClass = $this->em->getClassMetadata(ClassUtils::getClass($prevManagedCopy)); $prevClass = $this->em->getClassMetadata(get_class($prevManagedCopy));
if ($assoc['type'] & ClassMetadata::TO_ONE) { if ($assoc['type'] & ClassMetadata::TO_ONE) {
$prevClass->reflFields[$assocField]->setValue($prevManagedCopy, $managedCopy); $prevClass->reflFields[$assocField]->setValue($prevManagedCopy, $managedCopy);
@ -1922,7 +1921,7 @@ class UnitOfWork implements PropertyChangedListener
$visited[$oid] = $entity; // mark visited $visited[$oid] = $entity; // mark visited
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
if ($this->getEntityState($entity) !== self::STATE_MANAGED) { if ($this->getEntityState($entity) !== self::STATE_MANAGED) {
throw ORMInvalidArgumentException::entityNotManaged($entity); throw ORMInvalidArgumentException::entityNotManaged($entity);
@ -1944,7 +1943,7 @@ class UnitOfWork implements PropertyChangedListener
*/ */
private function cascadeRefresh($entity, array &$visited) private function cascadeRefresh($entity, array &$visited)
{ {
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$associationMappings = array_filter( $associationMappings = array_filter(
$class->associationMappings, $class->associationMappings,
@ -1985,7 +1984,7 @@ class UnitOfWork implements PropertyChangedListener
*/ */
private function cascadeDetach($entity, array &$visited) private function cascadeDetach($entity, array &$visited)
{ {
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$associationMappings = array_filter( $associationMappings = array_filter(
$class->associationMappings, $class->associationMappings,
@ -2027,7 +2026,7 @@ class UnitOfWork implements PropertyChangedListener
*/ */
private function cascadeMerge($entity, $managedCopy, array &$visited) private function cascadeMerge($entity, $managedCopy, array &$visited)
{ {
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$associationMappings = array_filter( $associationMappings = array_filter(
$class->associationMappings, $class->associationMappings,
@ -2065,7 +2064,7 @@ class UnitOfWork implements PropertyChangedListener
*/ */
private function cascadePersist($entity, array &$visited) private function cascadePersist($entity, array &$visited)
{ {
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$associationMappings = array_filter( $associationMappings = array_filter(
$class->associationMappings, $class->associationMappings,
@ -2106,7 +2105,7 @@ class UnitOfWork implements PropertyChangedListener
*/ */
private function cascadeRemove($entity, array &$visited) private function cascadeRemove($entity, array &$visited)
{ {
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$associationMappings = array_filter( $associationMappings = array_filter(
$class->associationMappings, $class->associationMappings,
@ -2152,7 +2151,7 @@ class UnitOfWork implements PropertyChangedListener
throw ORMInvalidArgumentException::entityNotManaged($entity); throw ORMInvalidArgumentException::entityNotManaged($entity);
} }
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
switch ($lockMode) { switch ($lockMode) {
case \Doctrine\DBAL\LockMode::OPTIMISTIC; case \Doctrine\DBAL\LockMode::OPTIMISTIC;
@ -2689,7 +2688,7 @@ class UnitOfWork implements PropertyChangedListener
*/ */
public function scheduleForDirtyCheck($entity) public function scheduleForDirtyCheck($entity)
{ {
$rootClassName = $this->em->getClassMetadata(ClassUtils::getClass($entity))->rootEntityName; $rootClassName = $this->em->getClassMetadata(get_class($entity))->rootEntityName;
$this->scheduledForDirtyCheck[$rootClassName][spl_object_hash($entity)] = $entity; $this->scheduledForDirtyCheck[$rootClassName][spl_object_hash($entity)] = $entity;
} }
@ -2827,7 +2826,7 @@ class UnitOfWork implements PropertyChangedListener
public function propertyChanged($entity, $propertyName, $oldValue, $newValue) public function propertyChanged($entity, $propertyName, $oldValue, $newValue)
{ {
$oid = spl_object_hash($entity); $oid = spl_object_hash($entity);
$class = $this->em->getClassMetadata(ClassUtils::getClass($entity)); $class = $this->em->getClassMetadata(get_class($entity));
$isAssocField = isset($class->associationMappings[$propertyName]); $isAssocField = isset($class->associationMappings[$propertyName]);