Passed
Pull Request — 2.8.x (#8022)
by Benjamin
08:51
created

testEmbeddedObjectShouldBeCreatedWhenIsNullableButHaveData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
eloc 10
c 3
b 1
f 0
dl 0
loc 18
rs 9.9332
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Doctrine\Tests\ORM\Functional;
4
5
use DateTime;
6
use Doctrine\Common\Reflection\RuntimePublicReflectionProperty;
7
use Doctrine\ORM\Mapping\MappingException;
8
use Doctrine\ORM\Mapping\ReflectionEmbeddedProperty;
9
use Doctrine\ORM\Query\QueryException;
10
use Doctrine\Tests\OrmFunctionalTestCase;
11
12
/**
13
 * @group DDC-93
14
 */
15
class ValueObjectsTest extends OrmFunctionalTestCase
16
{
17
    public function setUp()
18
    {
19
        parent::setUp();
20
21
        try {
22
            $this->_schemaTool->createSchema([
23
                $this->_em->getClassMetadata(DDC93Person::class),
24
                $this->_em->getClassMetadata(DDC93Address::class),
25
                $this->_em->getClassMetadata(DDC93Vehicle::class),
26
                $this->_em->getClassMetadata(DDC93Car::class),
27
                $this->_em->getClassMetadata(DDC3027Animal::class),
28
                $this->_em->getClassMetadata(DDC3027Dog::class),
29
                $this->_em->getClassMetadata(DDC3529Event::class),
30
            ]);
31
        } catch(\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
32
        }
33
    }
34
35
    public function testMetadataHasReflectionEmbeddablesAccessible()
36
    {
37
        $classMetadata = $this->_em->getClassMetadata(DDC93Person::class);
38
39
        $this->assertInstanceOf(RuntimePublicReflectionProperty::class, $classMetadata->getReflectionProperty('address'));
40
        $this->assertInstanceOf(ReflectionEmbeddedProperty::class, $classMetadata->getReflectionProperty('address.street'));
41
    }
42
43
    public function testCRUD()
44
    {
45
        $person = new DDC93Person();
46
        $person->name = "Tara";
47
        $person->address = new DDC93Address();
48
        $person->address->street = "United States of Tara Street";
49
        $person->address->zip = "12345";
50
        $person->address->city = "funkytown";
51
        $person->address->country = new DDC93Country('Germany');
52
53
        // 1. check saving value objects works
54
        $this->_em->persist($person);
55
        $this->_em->flush();
56
57
        $this->_em->clear();
58
59
        // 2. check loading value objects works
60
        $person = $this->_em->find(DDC93Person::class, $person->id);
61
62
        $this->assertInstanceOf(DDC93Address::class, $person->address);
63
        $this->assertEquals('United States of Tara Street', $person->address->street);
64
        $this->assertEquals('12345', $person->address->zip);
65
        $this->assertEquals('funkytown', $person->address->city);
66
        $this->assertInstanceOf(DDC93Country::class, $person->address->country);
67
        $this->assertEquals('Germany', $person->address->country->name);
68
69
        // 3. check changing value objects works
70
        $person->address->street = "Street";
71
        $person->address->zip = "54321";
72
        $person->address->city = "another town";
73
        $person->address->country->name = "United States of America";
74
        $this->_em->flush();
75
76
        $this->_em->clear();
77
78
        $person = $this->_em->find(DDC93Person::class, $person->id);
79
80
        $this->assertEquals('Street', $person->address->street);
81
        $this->assertEquals('54321', $person->address->zip);
82
        $this->assertEquals('another town', $person->address->city);
83
        $this->assertEquals('United States of America', $person->address->country->name);
84
85
        // 4. check deleting works
86
        $personId = $person->id;;
87
        $this->_em->remove($person);
88
        $this->_em->flush();
89
90
        $this->assertNull($this->_em->find(DDC93Person::class, $personId));
91
    }
92
93
    public function testLoadDql()
94
    {
95
        for ($i = 0; $i < 3; $i++) {
96
            $person = new DDC93Person();
97
            $person->name = "Donkey Kong$i";
98
            $person->address = new DDC93Address();
99
            $person->address->street = "Tree";
100
            $person->address->zip = "12345";
101
            $person->address->city = "funkytown";
102
            $person->address->country = new DDC93Country('United States of America');
103
104
            $this->_em->persist($person);
105
        }
106
107
        $this->_em->flush();
108
        $this->_em->clear();
109
110
        $dql = "SELECT p FROM " . __NAMESPACE__ . "\DDC93Person p";
111
        $persons = $this->_em->createQuery($dql)->getResult();
112
113
        $this->assertCount(3, $persons);
114
        foreach ($persons as $person) {
115
            $this->assertInstanceOf(DDC93Address::class, $person->address);
116
            $this->assertEquals('Tree', $person->address->street);
117
            $this->assertEquals('12345', $person->address->zip);
118
            $this->assertEquals('funkytown', $person->address->city);
119
            $this->assertInstanceOf(DDC93Country::class, $person->address->country);
120
            $this->assertEquals('United States of America', $person->address->country->name);
121
        }
122
123
        $dql = "SELECT p FROM " . __NAMESPACE__ . "\DDC93Person p";
124
        $persons = $this->_em->createQuery($dql)->getArrayResult();
125
126
        foreach ($persons as $person) {
127
            $this->assertEquals('Tree', $person['address.street']);
128
            $this->assertEquals('12345', $person['address.zip']);
129
            $this->assertEquals('funkytown', $person['address.city']);
130
            $this->assertEquals('United States of America', $person['address.country.name']);
131
        }
132
    }
133
134
    /**
135
     * @group dql
136
     */
137
    public function testDqlOnEmbeddedObjectsField()
138
    {
139
        if ($this->isSecondLevelCacheEnabled) {
140
            $this->markTestSkipped('SLC does not work with UPDATE/DELETE queries through EM.');
141
        }
142
143
        $person = new DDC93Person('Johannes', new DDC93Address('Moo', '12345', 'Karlsruhe', new DDC93Country('Germany')));
144
        $this->_em->persist($person);
145
        $this->_em->flush();
146
147
        // SELECT
148
        $selectDql = "SELECT p FROM " . __NAMESPACE__ ."\\DDC93Person p WHERE p.address.city = :city AND p.address.country.name = :country";
149
        $loadedPerson = $this->_em->createQuery($selectDql)
150
            ->setParameter('city', 'Karlsruhe')
151
            ->setParameter('country', 'Germany')
152
            ->getSingleResult();
153
        $this->assertEquals($person, $loadedPerson);
154
155
        $this->assertNull(
156
            $this->_em->createQuery($selectDql)
157
                ->setParameter('city', 'asdf')
158
                ->setParameter('country', 'Germany')
159
                ->getOneOrNullResult()
160
        );
161
162
        // UPDATE
163
        $updateDql = "UPDATE " . __NAMESPACE__ . "\\DDC93Person p SET p.address.street = :street, p.address.country.name = :country WHERE p.address.city = :city";
164
        $this->_em->createQuery($updateDql)
165
            ->setParameter('street', 'Boo')
166
            ->setParameter('country', 'DE')
167
            ->setParameter('city', 'Karlsruhe')
168
            ->execute();
169
170
        $this->_em->refresh($person);
171
        $this->assertEquals('Boo', $person->address->street);
172
        $this->assertEquals('DE', $person->address->country->name);
173
174
        // DELETE
175
        $this->_em->createQuery("DELETE " . __NAMESPACE__ . "\\DDC93Person p WHERE p.address.city = :city AND p.address.country.name = :country")
176
            ->setParameter('city', 'Karlsruhe')
177
            ->setParameter('country', 'DE')
178
            ->execute();
179
180
        $this->_em->clear();
181
        $this->assertNull($this->_em->find(DDC93Person::class, $person->id));
182
    }
183
184
    public function testPartialDqlOnEmbeddedObjectsField()
185
    {
186
        $person = new DDC93Person('Karl', new DDC93Address('Foo', '12345', 'Gosport', new DDC93Country('England')));
187
        $this->_em->persist($person);
188
        $this->_em->flush();
189
        $this->_em->clear();
190
191
        // Prove that the entity was persisted correctly.
192
        $dql = "SELECT p FROM " . __NAMESPACE__ ."\\DDC93Person p WHERE p.name = :name";
193
194
        $person = $this->_em->createQuery($dql)
195
            ->setParameter('name', 'Karl')
196
            ->getSingleResult();
197
198
        $this->assertEquals('Gosport', $person->address->city);
199
        $this->assertEquals('Foo', $person->address->street);
200
        $this->assertEquals('12345', $person->address->zip);
201
        $this->assertEquals('England', $person->address->country->name);
202
203
        // Clear the EM and prove that the embeddable can be the subject of a partial query.
204
        $this->_em->clear();
205
206
        $dql = "SELECT PARTIAL p.{id,address.city} FROM " . __NAMESPACE__ ."\\DDC93Person p WHERE p.name = :name";
207
208
        $person = $this->_em->createQuery($dql)
209
            ->setParameter('name', 'Karl')
210
            ->getSingleResult();
211
212
        // Selected field must be equal, all other fields must be null.
213
        $this->assertEquals('Gosport', $person->address->city);
214
        $this->assertNull($person->address->street);
215
        $this->assertNull($person->address->zip);
216
        $this->assertNull($person->address->country);
217
        $this->assertNull($person->name);
218
219
        // Clear the EM and prove that the embeddable can be the subject of a partial query regardless of attributes positions.
220
        $this->_em->clear();
221
222
        $dql = "SELECT PARTIAL p.{address.city, id} FROM " . __NAMESPACE__ ."\\DDC93Person p WHERE p.name = :name";
223
224
        $person = $this->_em->createQuery($dql)
225
            ->setParameter('name', 'Karl')
226
            ->getSingleResult();
227
228
        // Selected field must be equal, all other fields must be null.
229
        $this->assertEquals('Gosport', $person->address->city);
230
        $this->assertNull($person->address->street);
231
        $this->assertNull($person->address->zip);
232
        $this->assertNull($person->address->country);
233
        $this->assertNull($person->name);
234
    }
235
236
    public function testDqlWithNonExistentEmbeddableField()
237
    {
238
        $this->expectException(QueryException::class);
239
        $this->expectExceptionMessage('no field or association named address.asdfasdf');
240
241
        $this->_em->createQuery("SELECT p FROM " . __NAMESPACE__ . "\\DDC93Person p WHERE p.address.asdfasdf IS NULL")
242
            ->execute();
243
    }
244
245
    public function testPartialDqlWithNonExistentEmbeddableField()
246
    {
247
        $this->expectException(QueryException::class);
248
        $this->expectExceptionMessage("no mapped field named 'address.asdfasdf'");
249
250
        $this->_em->createQuery("SELECT PARTIAL p.{id,address.asdfasdf} FROM " . __NAMESPACE__ . "\\DDC93Person p")
251
            ->execute();
252
    }
253
254
    public function testEmbeddableWithInheritance()
255
    {
256
        $car = new DDC93Car(new DDC93Address('Foo', '12345', 'Asdf'));
257
        $this->_em->persist($car);
258
        $this->_em->flush();
259
260
        $reloadedCar = $this->_em->find(DDC93Car::class, $car->id);
261
        $this->assertEquals($car, $reloadedCar);
262
    }
263
264
    public function testInlineEmbeddableWithPrefix()
265
    {
266
        $metadata = $this->_em->getClassMetadata(DDC3028PersonWithPrefix::class);
267
268
        $this->assertEquals('foobar_id', $metadata->getColumnName('id.id'));
269
        $this->assertEquals('bloo_foo_id', $metadata->getColumnName('nested.nestedWithPrefix.id'));
270
        $this->assertEquals('bloo_nestedWithEmptyPrefix_id', $metadata->getColumnName('nested.nestedWithEmptyPrefix.id'));
271
        $this->assertEquals('bloo_id', $metadata->getColumnName('nested.nestedWithPrefixFalse.id'));
272
    }
273
274
    public function testInlineEmbeddableEmptyPrefix()
275
    {
276
        $metadata = $this->_em->getClassMetadata(DDC3028PersonEmptyPrefix::class);
277
278
        $this->assertEquals('id_id', $metadata->getColumnName('id.id'));
279
        $this->assertEquals('nested_foo_id', $metadata->getColumnName('nested.nestedWithPrefix.id'));
280
        $this->assertEquals('nested_nestedWithEmptyPrefix_id', $metadata->getColumnName('nested.nestedWithEmptyPrefix.id'));
281
        $this->assertEquals('nested_id', $metadata->getColumnName('nested.nestedWithPrefixFalse.id'));
282
    }
283
284
    public function testInlineEmbeddablePrefixFalse()
285
    {
286
        $expectedColumnName = 'id';
287
288
        $actualColumnName = $this->_em
289
            ->getClassMetadata(DDC3028PersonPrefixFalse::class)
290
            ->getColumnName('id.id');
291
292
        $this->assertEquals($expectedColumnName, $actualColumnName);
293
    }
294
295
    public function testInlineEmbeddableInMappedSuperClass()
296
    {
297
        $isFieldMapped = $this->_em
298
            ->getClassMetadata(DDC3027Dog::class)
299
            ->hasField('address.street');
300
301
        $this->assertTrue($isFieldMapped);
302
    }
303
304
    /**
305
     * @dataProvider getInfiniteEmbeddableNestingData
306
     */
307
    public function testThrowsExceptionOnInfiniteEmbeddableNesting($embeddableClassName, $declaredEmbeddableClassName)
308
    {
309
        $this->expectException(MappingException::class);
310
        $this->expectExceptionMessage(
311
            sprintf(
312
                'Infinite nesting detected for embedded property %s::nested. ' .
313
                'You cannot embed an embeddable from the same type inside an embeddable.',
314
                __NAMESPACE__ . '\\' . $declaredEmbeddableClassName
315
            )
316
        );
317
318
        $this->_schemaTool->createSchema(
319
            [
320
            $this->_em->getClassMetadata(__NAMESPACE__ . '\\' . $embeddableClassName),
321
            ]
322
        );
323
    }
324
325
    public function getInfiniteEmbeddableNestingData()
326
    {
327
        return [
328
            ['DDCInfiniteNestingEmbeddable', 'DDCInfiniteNestingEmbeddable'],
329
            ['DDCNestingEmbeddable1', 'DDCNestingEmbeddable4'],
330
        ];
331
    }
332
333
    public function testEmbeddableIsNotTransient()
334
    {
335
        $this->assertFalse($this->_em->getMetadataFactory()->isTransient(DDC93Address::class));
336
    }
337
338
    public function testNoErrorsShouldHappenWhenPersistingAnEntityWithNullableEmbedded()
339
    {
340
        $event         = new DDC3529Event();
341
        $event->name   = 'PHP Conference';
342
        $event->period = new DDC3529DateInterval(new DateTime('2015-01-20 08:00:00'), new DateTime('2015-01-23 19:00:00'));
343
344
        $this->_em->persist($event);
345
        $this->_em->flush();
346
347
        $this->assertNull($event->submissions);
348
349
        return $event;
350
    }
351
352
    /** @depends testNoErrorsShouldHappenWhenPersistingAnEntityWithNullableEmbedded */
353
    public function testEmbeddedObjectShouldNotBeCreatedWhenIsNullableAndHaveNoData(DDC3529Event $event)
354
    {
355
        $this->_em->clear();
356
357
        $event = $this->_em->find(DDC3529Event::class, $event->id);
358
359
        $this->assertEquals('PHP Conference', $event->name);
360
        $this->assertEquals('2015-01-20 08:00:00', $event->period->begin->format('Y-m-d H:i:s'));
361
        $this->assertEquals('2015-01-23 19:00:00', $event->period->end->format('Y-m-d H:i:s'));
362
        $this->assertNull($event->submissions);
363
364
        return $event;
365
    }
366
367
    /** @depends testEmbeddedObjectShouldNotBeCreatedWhenIsNullableAndHaveNoData */
368
    public function testEmbeddedObjectShouldBeCreatedWhenIsNullableButHaveData(DDC3529Event $event)
369
    {
370
        $this->_em->clear();
371
372
        $event = $this->_em->find(DDC3529Event::class, $event->id);
373
374
        $event->submissions = new DDC3529DateInterval(new DateTime('2014-11-20 08:00:00'), new DateTime('2014-12-23 19:00:00'));
375
376
        $this->_em->persist($event);
377
        $this->_em->flush();
378
        $this->_em->clear();
379
380
        $event = $this->_em->find(DDC3529Event::class, $event->id);
381
382
        $this->assertEquals('2014-11-20 08:00:00', $event->submissions->begin->format('Y-m-d H:i:s'));
383
        $this->assertEquals('2014-12-23 19:00:00', $event->submissions->end->format('Y-m-d H:i:s'));
384
385
        return $event;
386
    }
387
388
    /** @depends testEmbeddedObjectShouldBeCreatedWhenIsNullableButHaveData */
389
    public function testFindShouldReturnNullAfterTheObjectWasRemoved(DDC3529Event $event)
390
    {
391
        $this->_em->clear();
392
393
        $eventId = $event->id;
394
395
        $event = $this->_em->find(DDC3529Event::class, $eventId);
396
        $this->_em->remove($event);
397
        $this->_em->flush();
398
399
        $this->assertNull($this->_em->find(DDC3529Event::class, $eventId));
400
    }
401
}
402
403
404
/**
405
 * @Entity
406
 */
407
class DDC93Person
408
{
409
    /** @Id @GeneratedValue @Column(type="integer") */
410
    public $id;
411
412
    /** @Column(type="string") */
413
    public $name;
414
415
    /** @Embedded(class="DDC93Address") */
416
    public $address;
417
418
    /** @Embedded(class = "DDC93Timestamps") */
419
    public $timestamps;
420
421
    public function __construct($name = null, DDC93Address $address = null)
422
    {
423
        $this->name = $name;
424
        $this->address = $address;
425
        $this->timestamps = new DDC93Timestamps(new \DateTime);
426
    }
427
}
428
429
/**
430
 * @Embeddable
431
 */
432
class DDC93Timestamps
433
{
434
    /** @Column(type = "datetime") */
435
    public $createdAt;
436
437
    public function __construct(\DateTime $createdAt)
438
    {
439
        $this->createdAt = $createdAt;
440
    }
441
}
442
443
/**
444
 * @Entity
445
 *
446
 * @InheritanceType("SINGLE_TABLE")
447
 * @DiscriminatorColumn(name = "t", type = "string", length = 10)
448
 * @DiscriminatorMap({
449
 *     "v" = "Doctrine\Tests\ORM\Functional\DDC93Car",
450
 * })
451
 */
452
abstract class DDC93Vehicle
453
{
454
    /** @Id @GeneratedValue(strategy = "AUTO") @Column(type = "integer") */
455
    public $id;
456
457
    /** @Embedded(class = "DDC93Address") */
458
    public $address;
459
460
    public function __construct(DDC93Address $address)
461
    {
462
        $this->address = $address;
463
    }
464
}
465
466
/**
467
 * @Entity
468
 */
469
class DDC93Car extends DDC93Vehicle
470
{
471
}
472
473
/**
474
 * @Embeddable
475
 */
476
class DDC93Country
477
{
478
    /**
479
     * @Column(type="string", nullable=true)
480
     */
481
    public $name;
482
483
    public function __construct($name = null)
484
    {
485
        $this->name = $name;
486
    }
487
}
488
489
/**
490
 * @Embeddable
491
 */
492
class DDC93Address
493
{
494
    /**
495
     * @Column(type="string")
496
     */
497
    public $street;
498
    /**
499
     * @Column(type="string")
500
     */
501
    public $zip;
502
    /**
503
     * @Column(type="string")
504
     */
505
    public $city;
506
    /** @Embedded(class = "DDC93Country") */
507
    public $country;
508
509
    public function __construct($street = null, $zip = null, $city = null, DDC93Country $country = null)
510
    {
511
        $this->street = $street;
512
        $this->zip = $zip;
513
        $this->city = $city;
514
        $this->country = $country;
515
    }
516
}
517
518
/** @Entity */
519
class DDC93Customer
520
{
521
    /** @Id @GeneratedValue @Column(type="integer") */
522
    private $id;
523
524
    /** @Embedded(class = "DDC93ContactInfo", columnPrefix = "contact_info_") */
525
    private $contactInfo;
0 ignored issues
show
introduced by
The private property $contactInfo is not used, and could be removed.
Loading history...
526
}
527
528
/** @Embeddable */
529
class DDC93ContactInfo
530
{
531
    /**
532
     * @Column(type="string")
533
     */
534
    public $email;
535
    /** @Embedded(class = "DDC93Address") */
536
    public $address;
537
}
538
539
/**
540
 * @Entity
541
 */
542
class DDC3028PersonWithPrefix
543
{
544
    /** @Embedded(class="DDC3028Id", columnPrefix = "foobar_") */
545
    public $id;
546
547
    /** @Embedded(class="DDC3028NestedEmbeddable", columnPrefix = "bloo_") */
548
    public $nested;
549
550
    public function __construct(DDC3028Id $id = null, DDC3028NestedEmbeddable $nested = null)
551
    {
552
        $this->id = $id;
553
        $this->nested = $nested;
554
    }
555
}
556
557
/**
558
 * @Entity
559
 */
560
class DDC3028PersonEmptyPrefix
561
{
562
    /** @Embedded(class="DDC3028Id", columnPrefix = "") */
563
    public $id;
564
565
    /** @Embedded(class="DDC3028NestedEmbeddable", columnPrefix = "") */
566
    public $nested;
567
568
    public function __construct(DDC3028Id $id = null, DDC3028NestedEmbeddable $nested = null)
569
    {
570
        $this->id = $id;
571
        $this->nested = $nested;
572
    }
573
}
574
575
/**
576
 * @Entity
577
 */
578
class DDC3028PersonPrefixFalse
579
{
580
    /** @Embedded(class="DDC3028Id", columnPrefix = false) */
581
    public $id;
582
583
    public function __construct(DDC3028Id $id = null)
584
    {
585
        $this->id = $id;
586
    }
587
}
588
589
/**
590
 * @Embeddable
591
 */
592
class DDC3028Id
593
{
594
    /**
595
     * @Id @Column(type="string")
596
     */
597
    public $id;
598
599
    public function __construct($id = null)
600
    {
601
        $this->id = $id;
602
    }
603
}
604
605
/**
606
 * @Embeddable
607
 */
608
class DDC3028NestedEmbeddable
609
{
610
    /** @Embedded(class="DDC3028Id", columnPrefix = "foo_") */
611
    public $nestedWithPrefix;
612
613
    /** @Embedded(class="DDC3028Id", columnPrefix = "") */
614
    public $nestedWithEmptyPrefix;
615
616
    /** @Embedded(class="DDC3028Id", columnPrefix = false) */
617
    public $nestedWithPrefixFalse;
618
619
    public function __construct(
620
        DDC3028Id $nestedWithPrefix = null,
621
        DDC3028Id $nestedWithEmptyPrefix = null,
622
        DDC3028Id $nestedWithPrefixFalse = null
623
    ) {
624
        $this->nestedWithPrefix = $nestedWithPrefix;
625
        $this->nestedWithEmptyPrefix = $nestedWithEmptyPrefix;
626
        $this->nestedWithPrefixFalse = $nestedWithPrefixFalse;
627
    }
628
}
629
630
/**
631
 * @MappedSuperclass
632
 */
633
abstract class DDC3027Animal
634
{
635
    /** @Id @GeneratedValue(strategy = "AUTO") @Column(type = "integer") */
636
    public $id;
637
638
    /** @Embedded(class = "DDC93Address") */
639
    public $address;
640
}
641
642
/**
643
 * @Entity
644
 */
645
class DDC3027Dog extends DDC3027Animal
646
{
647
}
648
649
/**
650
 * @Embeddable
651
 */
652
class DDCInfiniteNestingEmbeddable
653
{
654
    /** @Embedded(class="DDCInfiniteNestingEmbeddable") */
655
    public $nested;
656
}
657
658
/**
659
 * @Embeddable
660
 */
661
class DDCNestingEmbeddable1
662
{
663
    /** @Embedded(class="DDC3028Id") */
664
    public $id1;
665
666
    /** @Embedded(class="DDC3028Id") */
667
    public $id2;
668
669
    /** @Embedded(class="DDCNestingEmbeddable2") */
670
    public $nested;
671
}
672
673
/**
674
 * @Embeddable
675
 */
676
class DDCNestingEmbeddable2
677
{
678
    /** @Embedded(class="DDC3028Id") */
679
    public $id1;
680
681
    /** @Embedded(class="DDC3028Id") */
682
    public $id2;
683
684
    /** @Embedded(class="DDCNestingEmbeddable3") */
685
    public $nested;
686
}
687
688
/**
689
 * @Embeddable
690
 */
691
class DDCNestingEmbeddable3
692
{
693
    /** @Embedded(class="DDC3028Id") */
694
    public $id1;
695
696
    /** @Embedded(class="DDC3028Id") */
697
    public $id2;
698
699
    /** @Embedded(class="DDCNestingEmbeddable4") */
700
    public $nested;
701
}
702
703
/**
704
 * @Embeddable
705
 */
706
class DDCNestingEmbeddable4
707
{
708
    /** @Embedded(class="DDC3028Id") */
709
    public $id1;
710
711
    /** @Embedded(class="DDC3028Id") */
712
    public $id2;
713
714
    /** @Embedded(class="DDCNestingEmbeddable1") */
715
    public $nested;
716
}
717
718
/**
719
 * @Embeddable
720
 */
721
class DDC3529DateInterval
722
{
723
    /** @Column(type = "datetime") */
724
    public $begin;
725
726
    /** @Column(type = "datetime") */
727
    public $end;
728
729
    public function __construct(DateTime $begin, DateTime $end)
730
    {
731
        $this->begin = $begin;
732
        $this->end   = $end;
733
    }
734
}
735
736
/**
737
 * @Entity
738
 */
739
class DDC3529Event
740
{
741
    /** @Id @GeneratedValue @Column(type="integer") */
742
    public $id;
743
744
    /** @Column(type = "string") */
745
    public $name;
746
747
    /** @Embedded(class = "DDC3529DateInterval") */
748
    public $period;
749
750
    /** @Embedded(class = "DDC3529DateInterval", nullable = true) */
751
    public $submissions;
752
}
753