_schemaTool->createSchema(array( $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Person'), $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Address'), $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Vehicle'), $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Car'), $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3027Animal'), $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3027Dog'), )); } catch(\Exception $e) { } } public function testCRUD() { $person = new DDC93Person(); $person->name = "Tara"; $person->address = new DDC93Address(); $person->address->street = "United States of Tara Street"; $person->address->zip = "12345"; $person->address->city = "funkytown"; $person->address->country = new DDC93Country('Germany'); // 1. check saving value objects works $this->_em->persist($person); $this->_em->flush(); $this->_em->clear(); // 2. check loading value objects works $person = $this->_em->find(DDC93Person::CLASSNAME, $person->id); $this->assertInstanceOf(DDC93Address::CLASSNAME, $person->address); $this->assertEquals('United States of Tara Street', $person->address->street); $this->assertEquals('12345', $person->address->zip); $this->assertEquals('funkytown', $person->address->city); $this->assertInstanceOf(DDC93Country::CLASSNAME, $person->address->country); $this->assertEquals('Germany', $person->address->country->name); // 3. check changing value objects works $person->address->street = "Street"; $person->address->zip = "54321"; $person->address->city = "another town"; $person->address->country->name = "United States of America"; $this->_em->flush(); $this->_em->clear(); $person = $this->_em->find(DDC93Person::CLASSNAME, $person->id); $this->assertEquals('Street', $person->address->street); $this->assertEquals('54321', $person->address->zip); $this->assertEquals('another town', $person->address->city); $this->assertEquals('United States of America', $person->address->country->name); // 4. check deleting works $personId = $person->id;; $this->_em->remove($person); $this->_em->flush(); $this->assertNull($this->_em->find(DDC93Person::CLASSNAME, $personId)); } public function testLoadDql() { for ($i = 0; $i < 3; $i++) { $person = new DDC93Person(); $person->name = "Donkey Kong$i"; $person->address = new DDC93Address(); $person->address->street = "Tree"; $person->address->zip = "12345"; $person->address->city = "funkytown"; $person->address->country = new DDC93Country('United States of America'); $this->_em->persist($person); } $this->_em->flush(); $this->_em->clear(); $dql = "SELECT p FROM " . __NAMESPACE__ . "\DDC93Person p"; $persons = $this->_em->createQuery($dql)->getResult(); $this->assertCount(3, $persons); foreach ($persons as $person) { $this->assertInstanceOf(DDC93Address::CLASSNAME, $person->address); $this->assertEquals('Tree', $person->address->street); $this->assertEquals('12345', $person->address->zip); $this->assertEquals('funkytown', $person->address->city); $this->assertInstanceOf(DDC93Country::CLASSNAME, $person->address->country); $this->assertEquals('United States of America', $person->address->country->name); } $dql = "SELECT p FROM " . __NAMESPACE__ . "\DDC93Person p"; $persons = $this->_em->createQuery($dql)->getArrayResult(); foreach ($persons as $person) { $this->assertEquals('Tree', $person['address.street']); $this->assertEquals('12345', $person['address.zip']); $this->assertEquals('funkytown', $person['address.city']); $this->assertEquals('United States of America', $person['address.country.name']); } } /** * @group dql */ public function testDqlOnEmbeddedObjectsField() { if ($this->isSecondLevelCacheEnabled) { $this->markTestSkipped('SLC does not work with UPDATE/DELETE queries through EM.'); } $person = new DDC93Person('Johannes', new DDC93Address('Moo', '12345', 'Karlsruhe', new DDC93Country('Germany'))); $this->_em->persist($person); $this->_em->flush($person); // SELECT $selectDql = "SELECT p FROM " . __NAMESPACE__ ."\\DDC93Person p WHERE p.address.city = :city AND p.address.country.name = :country"; $loadedPerson = $this->_em->createQuery($selectDql) ->setParameter('city', 'Karlsruhe') ->setParameter('country', 'Germany') ->getSingleResult(); $this->assertEquals($person, $loadedPerson); $this->assertNull( $this->_em->createQuery($selectDql) ->setParameter('city', 'asdf') ->setParameter('country', 'Germany') ->getOneOrNullResult() ); // UPDATE $updateDql = "UPDATE " . __NAMESPACE__ . "\\DDC93Person p SET p.address.street = :street, p.address.country.name = :country WHERE p.address.city = :city"; $this->_em->createQuery($updateDql) ->setParameter('street', 'Boo') ->setParameter('country', 'DE') ->setParameter('city', 'Karlsruhe') ->execute(); $this->_em->refresh($person); $this->assertEquals('Boo', $person->address->street); $this->assertEquals('DE', $person->address->country->name); // DELETE $this->_em->createQuery("DELETE " . __NAMESPACE__ . "\\DDC93Person p WHERE p.address.city = :city AND p.address.country.name = :country") ->setParameter('city', 'Karlsruhe') ->setParameter('country', 'DE') ->execute(); $this->_em->clear(); $this->assertNull($this->_em->find(__NAMESPACE__.'\\DDC93Person', $person->id)); } public function testDqlWithNonExistentEmbeddableField() { $this->setExpectedException('Doctrine\ORM\Query\QueryException', 'no field or association named address.asdfasdf'); $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); } public function testInlineEmbeddableWithPrefix() { $metadata = $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3028PersonWithPrefix'); $this->assertEquals('foobar_id', $metadata->getColumnName('id.id')); $this->assertEquals('bloo_foo_id', $metadata->getColumnName('nested.nestedWithPrefix.id')); $this->assertEquals('bloo_nestedWithEmptyPrefix_id', $metadata->getColumnName('nested.nestedWithEmptyPrefix.id')); $this->assertEquals('bloo_id', $metadata->getColumnName('nested.nestedWithPrefixFalse.id')); } public function testInlineEmbeddableEmptyPrefix() { $metadata = $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3028PersonEmptyPrefix'); $this->assertEquals('id_id', $metadata->getColumnName('id.id')); $this->assertEquals('nested_foo_id', $metadata->getColumnName('nested.nestedWithPrefix.id')); $this->assertEquals('nested_nestedWithEmptyPrefix_id', $metadata->getColumnName('nested.nestedWithEmptyPrefix.id')); $this->assertEquals('nested_id', $metadata->getColumnName('nested.nestedWithPrefixFalse.id')); } public function testInlineEmbeddablePrefixFalse() { $expectedColumnName = 'id'; $actualColumnName = $this->_em ->getClassMetadata(__NAMESPACE__ . '\DDC3028PersonPrefixFalse') ->getColumnName('id.id'); $this->assertEquals($expectedColumnName, $actualColumnName); } public function testInlineEmbeddableInMappedSuperClass() { $isFieldMapped = $this->_em ->getClassMetadata(__NAMESPACE__ . '\DDC3027Dog') ->hasField('address.street'); $this->assertTrue($isFieldMapped); } /** * @dataProvider getInfiniteEmbeddableNestingData */ public function testThrowsExceptionOnInfiniteEmbeddableNesting($embeddableClassName, $declaredEmbeddableClassName) { $this->setExpectedException( 'Doctrine\ORM\Mapping\MappingException', sprintf( 'Infinite nesting detected for embedded property %s::nested. ' . 'You cannot embed an embeddable from the same type inside an embeddable.', __NAMESPACE__ . '\\' . $declaredEmbeddableClassName ) ); $this->_schemaTool->createSchema(array( $this->_em->getClassMetadata(__NAMESPACE__ . '\\' . $embeddableClassName), )); } public function getInfiniteEmbeddableNestingData() { return array( array('DDCInfiniteNestingEmbeddable', 'DDCInfiniteNestingEmbeddable'), array('DDCNestingEmbeddable1', 'DDCNestingEmbeddable4'), ); } } /** * @Entity */ class DDC93Person { const CLASSNAME = __CLASS__; /** @Id @GeneratedValue @Column(type="integer") */ public $id; /** @Column(type="string") */ public $name; /** @Embedded(class="DDC93Address") */ public $address; /** @Embedded(class = "DDC93Timestamps") */ public $timestamps; public function __construct($name = null, DDC93Address $address = null) { $this->name = $name; $this->address = $address; $this->timestamps = new DDC93Timestamps(new \DateTime); } } /** * @Embeddable */ class DDC93Timestamps { /** @Column(type = "datetime") */ public $createdAt; public function __construct(\DateTime $createdAt) { $this->createdAt = $createdAt; } } /** * @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 */ class DDC93Country { const CLASSNAME = __CLASS__; /** * @Column(type="string", nullable=true) */ public $name; public function __construct($name = null) { $this->name = $name; } } /** * @Embeddable */ class DDC93Address { const CLASSNAME = __CLASS__; /** * @Column(type="string") */ public $street; /** * @Column(type="string") */ public $zip; /** * @Column(type="string") */ public $city; /** @Embedded(class = "DDC93Country") */ public $country; public function __construct($street = null, $zip = null, $city = null, DDC93Country $country = null) { $this->street = $street; $this->zip = $zip; $this->city = $city; $this->country = $country; } } /** @Entity */ class DDC93Customer { /** @Id @GeneratedValue @Column(type="integer") */ private $id; /** @Embedded(class = "DDC93ContactInfo", columnPrefix = "contact_info_") */ private $contactInfo; } /** @Embeddable */ class DDC93ContactInfo { const CLASSNAME = __CLASS__; /** * @Column(type="string") */ public $email; /** @Embedded(class = "DDC93Address") */ public $address; } /** * @Entity */ class DDC3028PersonWithPrefix { const CLASSNAME = __CLASS__; /** @Embedded(class="DDC3028Id", columnPrefix = "foobar_") */ public $id; /** @Embedded(class="DDC3028NestedEmbeddable", columnPrefix = "bloo_") */ public $nested; public function __construct(DDC3028Id $id = null, DDC3028NestedEmbeddable $nested = null) { $this->id = $id; $this->nested = $nested; } } /** * @Entity */ class DDC3028PersonEmptyPrefix { const CLASSNAME = __CLASS__; /** @Embedded(class="DDC3028Id", columnPrefix = "") */ public $id; /** @Embedded(class="DDC3028NestedEmbeddable", columnPrefix = "") */ public $nested; public function __construct(DDC3028Id $id = null, DDC3028NestedEmbeddable $nested = null) { $this->id = $id; $this->nested = $nested; } } /** * @Entity */ class DDC3028PersonPrefixFalse { const CLASSNAME = __CLASS__; /** @Embedded(class="DDC3028Id", columnPrefix = false) */ public $id; public function __construct(DDC3028Id $id = null) { $this->id = $id; } } /** * @Embeddable */ class DDC3028Id { const CLASSNAME = __CLASS__; /** * @Id @Column(type="string") */ public $id; public function __construct($id = null) { $this->id = $id; } } /** * @Embeddable */ class DDC3028NestedEmbeddable { const CLASSNAME = __CLASS__; /** @Embedded(class="DDC3028Id", columnPrefix = "foo_") */ public $nestedWithPrefix; /** @Embedded(class="DDC3028Id", columnPrefix = "") */ public $nestedWithEmptyPrefix; /** @Embedded(class="DDC3028Id", columnPrefix = false) */ public $nestedWithPrefixFalse; public function __construct( DDC3028Id $nestedWithPrefix = null, DDC3028Id $nestedWithEmptyPrefix = null, DDC3028Id $nestedWithPrefixFalse = null ) { $this->nestedWithPrefix = $nestedWithPrefix; $this->nestedWithEmptyPrefix = $nestedWithEmptyPrefix; $this->nestedWithPrefixFalse = $nestedWithPrefixFalse; } } /** * @MappedSuperclass */ abstract class DDC3027Animal { /** @Id @GeneratedValue(strategy = "AUTO") @Column(type = "integer") */ public $id; /** @Embedded(class = "DDC93Address") */ public $address; } /** * @Entity */ class DDC3027Dog extends DDC3027Animal { } /** * @Embeddable */ class DDCInfiniteNestingEmbeddable { /** @Embedded(class="DDCInfiniteNestingEmbeddable") */ public $nested; } /** * @Embeddable */ class DDCNestingEmbeddable1 { /** @Embedded(class="DDC3028Id") */ public $id1; /** @Embedded(class="DDC3028Id") */ public $id2; /** @Embedded(class="DDCNestingEmbeddable2") */ public $nested; } /** * @Embeddable */ class DDCNestingEmbeddable2 { /** @Embedded(class="DDC3028Id") */ public $id1; /** @Embedded(class="DDC3028Id") */ public $id2; /** @Embedded(class="DDCNestingEmbeddable3") */ public $nested; } /** * @Embeddable */ class DDCNestingEmbeddable3 { /** @Embedded(class="DDC3028Id") */ public $id1; /** @Embedded(class="DDC3028Id") */ public $id2; /** @Embedded(class="DDCNestingEmbeddable4") */ public $nested; } /** * @Embeddable */ class DDCNestingEmbeddable4 { /** @Embedded(class="DDC3028Id") */ public $id1; /** @Embedded(class="DDC3028Id") */ public $id2; /** @Embedded(class="DDCNestingEmbeddable1") */ public $nested; }