adds support & tests for embeddables in inheritance schemes
This commit is contained in:
parent
d4e6618b28
commit
ece62d6ad7
@ -96,6 +96,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
$class->setIdGeneratorType($parent->generatorType);
|
||||
$this->addInheritedFields($class, $parent);
|
||||
$this->addInheritedRelations($class, $parent);
|
||||
$this->addInheritedEmbeddedClasses($class, $parent);
|
||||
$class->setIdentifier($parent->identifier);
|
||||
$class->setVersioned($parent->isVersioned);
|
||||
$class->setVersionField($parent->versionField);
|
||||
@ -141,7 +142,11 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
}
|
||||
|
||||
foreach ($class->embeddedClasses as $property => $embeddableClass) {
|
||||
$embeddableMetadata = $this->getMetadataFor($embeddableClass);
|
||||
if (isset($embeddableClass['inherited'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
|
||||
$class->inlineEmbeddable($property, $embeddableMetadata);
|
||||
}
|
||||
|
||||
@ -343,6 +348,20 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
}
|
||||
}
|
||||
|
||||
private function addInheritedEmbeddedClasses(ClassMetadata $subClass, ClassMetadata $parentClass)
|
||||
{
|
||||
foreach ($parentClass->embeddedClasses as $field => $embeddedClass) {
|
||||
if ( ! isset($embeddedClass['inherited']) && ! $parentClass->isMappedSuperclass) {
|
||||
$embeddedClass['inherited'] = $parentClass->name;
|
||||
}
|
||||
if ( ! isset($embeddedClass['declared'])) {
|
||||
$embeddedClass['declared'] = $parentClass->name;
|
||||
}
|
||||
|
||||
$subClass->embeddedClasses[$field] = $embeddedClass;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds inherited named queries to the subclass mapping.
|
||||
*
|
||||
|
@ -899,10 +899,12 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
|
||||
foreach ($this->fieldMappings as $field => $mapping) {
|
||||
if (isset($mapping['declaredField'])) {
|
||||
$declaringClass = isset($this->embeddedClasses[$field]['declared']) ? $this->embeddedClasses[$field]['declared'] : $this->name;
|
||||
|
||||
$this->reflFields[$field] = new ReflectionEmbeddedProperty(
|
||||
$reflService->getAccessibleProperty($this->name, $mapping['declaredField']),
|
||||
$reflService->getAccessibleProperty($this->embeddedClasses[$mapping['declaredField']], $mapping['originalField']),
|
||||
$this->embeddedClasses[$mapping['declaredField']]
|
||||
$reflService->getAccessibleProperty($declaringClass, $mapping['declaredField']),
|
||||
$reflService->getAccessibleProperty($this->embeddedClasses[$mapping['declaredField']]['class'], $mapping['originalField']),
|
||||
$this->embeddedClasses[$mapping['declaredField']]['class']
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@ -2110,6 +2112,11 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
return isset($this->associationMappings[$fieldName]['inherited']);
|
||||
}
|
||||
|
||||
public function isInheritedEmbeddedClass($fieldName)
|
||||
{
|
||||
return isset($this->embeddedClasses[$fieldName]['inherited']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the primary table the class is mapped to.
|
||||
*
|
||||
@ -3079,7 +3086,9 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
{
|
||||
$this->assertFieldNotMapped($mapping['fieldName']);
|
||||
|
||||
$this->embeddedClasses[$mapping['fieldName']] = $this->fullyQualifiedClassName($mapping['class']);
|
||||
$this->embeddedClasses[$mapping['fieldName']] = array(
|
||||
'class' => $this->fullyQualifiedClassName($mapping['class'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,7 +242,9 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
||
|
||||
$metadata->isInheritedField($property->name)
|
||||
||
|
||||
$metadata->isInheritedAssociation($property->name)) {
|
||||
$metadata->isInheritedAssociation($property->name)
|
||||
||
|
||||
$metadata->isInheritedEmbeddedClass($property->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Person'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Address'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Vehicle'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Car'),
|
||||
));
|
||||
} catch(\Exception $e) {
|
||||
}
|
||||
@ -146,6 +148,16 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_em->createQuery("SELECT p FROM " . __NAMESPACE__ . "\\DDC93Person p WHERE p.address.asdfasdf IS NULL")
|
||||
->execute();
|
||||
}
|
||||
|
||||
public function testEmbeddableWithInheritance()
|
||||
{
|
||||
$car = new DDC93Car(new DDC93Address('Foo', '12345', 'Asdf'));
|
||||
$this->_em->persist($car);
|
||||
$this->_em->flush($car);
|
||||
|
||||
$reloadedCar = $this->_em->find(__NAMESPACE__.'\\DDC93Car', $car->id);
|
||||
$this->assertEquals($car, $reloadedCar);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,6 +183,36 @@ class DDC93Person
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*
|
||||
* @InheritanceType("SINGLE_TABLE")
|
||||
* @DiscriminatorColumn(name = "t", type = "string", length = 10)
|
||||
* @DiscriminatorMap({
|
||||
* "v" = "Doctrine\Tests\ORM\Functional\DDC93Car",
|
||||
* })
|
||||
*/
|
||||
abstract class DDC93Vehicle
|
||||
{
|
||||
/** @Id @GeneratedValue(strategy = "AUTO") @Column(type = "integer") */
|
||||
public $id;
|
||||
|
||||
/** @Embedded(class = "DDC93Address") */
|
||||
public $address;
|
||||
|
||||
public function __construct(DDC93Address $address)
|
||||
{
|
||||
$this->address = $address;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC93Car extends DDC93Vehicle
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Embeddable
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user