AbstractMappingDriverTest   C
last analyzed

Complexity

Total Complexity 56

Size/Duplication

Total Lines 1035
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 452
c 3
b 0
f 0
dl 0
loc 1035
rs 5.5199
wmc 56

51 Methods

Rating   Name   Duplication   Size   Complexity  
A testIdentifier() 0 15 1
A testAssociationOverridesMapping() 0 69 1
A testFieldOptions() 0 10 1
A testEntityListeners() 0 24 1
A testFetchOverrideMapping() 0 10 1
A testStringFieldMappings() 0 12 1
A testEntityCustomGenerator() 0 7 1
A testInvalidEntityOrMappedSuperClassShouldMentionParentClasses() 0 6 1
A testLifecycleCallbacks() 0 7 1
A testLifecycleCallbacksSupportMultipleMethodNames() 0 6 1
A testManyToManyAssociationWithCascadeAll() 0 15 1
A testOwningOneToOneAssociation() 0 12 1
A testInversedByOverrideMapping() 0 12 1
A testOneToOneUnidirectional() 0 8 1
A testJoinColumnOnDelete() 0 9 1
A testIdFieldOptions() 0 10 1
A testFieldMappingsColumnNames() 0 11 1
A createClassMetadataFactory() 0 10 2
A testJoinColumnUniqueAndNullable() 0 12 1
A testEntitySequence() 0 12 1
A testEntityTableNameAndInheritance() 0 8 1
A setUp() 0 25 1
A createClassMetadata() 0 5 1
A testManyToManyBidirectional() 0 14 1
A testVersionProperty() 0 9 1
A testEntityUniqueConstraints() 0 16 1
A testEntityListenersOverride() 0 27 1
A testSchemaDefinitionViaSchemaDefinedInTableNameInTableAnnotationProperty() 0 7 1
A testBooleanValuesForOptionIsSetCorrectly() 0 13 1
A testDefaultFieldType() 0 24 1
A testManyToOneBidirectional() 0 14 1
A testEntityIndexes() 0 26 1
A testSecondLevelCacheMapping() 0 24 1
A testNamingStrategy() 0 16 1
A testDiscriminatorColumnDefaultType() 0 13 2
A testDiscriminatorColumnDefinition() 0 10 1
A testProperties() 0 11 1
A testInverseOneToManyAssociation() 0 16 1
A testOneToOneBidirectional() 0 14 1
A testSchemaDefinitionViaExplicitTableSchemaAnnotationProperty() 0 7 1
A testAttributeOverridesMapping() 0 60 1
A testIdentifierColumnDefinition() 0 9 1
A testIdentifierRequiredShouldMentionParentClasses() 0 8 1
A testDiscriminatorColumnDefaults() 0 17 2
A testEntityOptions() 0 12 1
A testColumnDefinition() 0 14 1
A testDiscriminatorColumnDefaultName() 0 13 2
A testMappedSuperclassWithRepository() 0 21 1
A testEntityIndexFlagsAndPartialIndexes() 0 15 1
A testManyToOneUnidirectional() 0 8 1
A testDiscriminatorColumnDefaultLength() 0 13 2

How to fix   Complexity   

Complex Class

Complex classes like AbstractMappingDriverTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AbstractMappingDriverTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Mapping;
6
7
use Doctrine\DBAL\Platforms\AbstractPlatform;
8
use Doctrine\DBAL\Types\Type;
9
use Doctrine\ORM\Annotation as ORM;
10
use Doctrine\ORM\EntityManagerInterface;
11
use Doctrine\ORM\Events;
12
use Doctrine\ORM\Mapping;
13
use Doctrine\ORM\Mapping\ClassMetadata;
14
use Doctrine\ORM\Mapping\ClassMetadataFactory;
15
use Doctrine\ORM\Mapping\Factory\DefaultNamingStrategy;
16
use Doctrine\ORM\Mapping\Factory\UnderscoreNamingStrategy;
17
use Doctrine\ORM\Mapping\MappingException;
18
use Doctrine\ORM\Reflection\ReflectionService;
19
use Doctrine\ORM\Sequencing\Generator\Generator;
20
use Doctrine\ORM\Sequencing\Generator\SequenceGenerator;
21
use Doctrine\Tests\Models\Cache\City;
22
use Doctrine\Tests\Models\Company\CompanyContract;
23
use Doctrine\Tests\Models\Company\CompanyContractListener;
24
use Doctrine\Tests\Models\Company\CompanyFixContract;
25
use Doctrine\Tests\Models\Company\CompanyFlexContract;
26
use Doctrine\Tests\Models\Company\CompanyFlexUltraContract;
27
use Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener;
28
use Doctrine\Tests\Models\DDC1476\DDC1476EntityWithDefaultFieldType;
29
use Doctrine\Tests\Models\DDC2825\ExplicitSchemaAndTable;
30
use Doctrine\Tests\Models\DDC2825\SchemaAndTableInTableName;
31
use Doctrine\Tests\Models\DDC3579\DDC3579Admin;
32
use Doctrine\Tests\Models\DDC5934\DDC5934Contract;
33
use Doctrine\Tests\Models\DDC869\DDC869ChequePayment;
34
use Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment;
35
use Doctrine\Tests\Models\DDC869\DDC869PaymentRepository;
36
use Doctrine\Tests\Models\DDC889\DDC889Class;
37
use Doctrine\Tests\Models\DDC889\DDC889Entity;
38
use Doctrine\Tests\Models\DDC964\DDC964Admin;
39
use Doctrine\Tests\Models\DDC964\DDC964Guest;
40
use Doctrine\Tests\Models\Quote;
41
use Doctrine\Tests\OrmTestCase;
42
use const CASE_UPPER;
43
use function get_class;
44
use function iterator_to_array;
45
use function reset;
46
use function strpos;
47
48
abstract class AbstractMappingDriverTest extends OrmTestCase
49
{
50
    /** @var AbstractPlatform */
51
    protected $targetPlatform;
52
53
    /** @var Mapping\ClassMetadataBuildingContext */
54
    protected $metadataBuildingContext;
55
56
    protected function setUp() : void
57
    {
58
        parent::setUp();
59
60
        $this->targetPlatform = $this->createMock(AbstractPlatform::class);
61
62
        $this->targetPlatform
63
            ->expects($this->any())
64
            ->method('prefersSequences')
65
            ->will($this->returnValue(true));
66
67
        $this->targetPlatform
68
            ->expects($this->any())
69
            ->method('usesSequenceEmulatedIdentityColumns')
70
            ->will($this->returnValue(true));
71
72
        $this->targetPlatform
73
            ->expects($this->any())
74
            ->method('fixSchemaElementName')
75
            ->will($this->returnArgument(0));
76
77
        $this->metadataBuildingContext = new Mapping\ClassMetadataBuildingContext(
78
            $this->createMock(ClassMetadataFactory::class),
79
            $this->createMock(ReflectionService::class),
80
            $this->targetPlatform
81
        );
82
    }
83
84
    abstract protected function loadDriver();
85
86
    public function createClassMetadata($entityClassName)
87
    {
88
        $mappingDriver = $this->loadDriver();
89
90
        return $mappingDriver->loadMetadataForClass($entityClassName, null, $this->metadataBuildingContext);
91
    }
92
93
    protected function createClassMetadataFactory(?EntityManagerInterface $em = null) : ClassMetadataFactory
94
    {
95
        $driver  = $this->loadDriver();
96
        $em      = $em ?: $this->getTestEntityManager();
97
        $factory = new ClassMetadataFactory();
98
99
        $em->getConfiguration()->setMetadataDriverImpl($driver);
100
        $factory->setEntityManager($em);
101
102
        return $factory;
103
    }
104
105
    public function testEntityTableNameAndInheritance() : ClassMetadata
106
    {
107
        $class = $this->createClassMetadata(User::class);
108
109
        self::assertEquals('cms_users', $class->getTableName());
110
        self::assertEquals(Mapping\InheritanceType::NONE, $class->inheritanceType);
111
112
        return $class;
113
    }
114
115
    public function testEntityIndexes() : ClassMetadata
116
    {
117
        $class = $this->createClassMetadata('Doctrine\Tests\ORM\Mapping\User');
118
119
        self::assertCount(2, $class->table->getIndexes());
120
        self::assertEquals(
121
            [
122
                'name_idx' => [
123
                    'name'    => 'name_idx',
124
                    'columns' => ['name'],
125
                    'unique'  => false,
126
                    'options' => [],
127
                    'flags'   => [],
128
                ],
129
                0 => [
130
                    'name'    => null,
131
                    'columns' => ['user_email'],
132
                    'unique'  => false,
133
                    'options' => [],
134
                    'flags'   => [],
135
                ],
136
            ],
137
            $class->table->getIndexes()
138
        );
139
140
        return $class;
141
    }
142
143
    public function testEntityIndexFlagsAndPartialIndexes() : void
144
    {
145
        $class = $this->createClassMetadata(Comment::class);
146
147
        self::assertEquals(
148
            [
149
                0 => [
150
                    'name'    => null,
151
                    'columns' => ['content'],
152
                    'unique'  => false,
153
                    'flags'   => ['fulltext'],
154
                    'options' => ['where' => 'content IS NOT NULL'],
155
                ],
156
            ],
157
            $class->table->getIndexes()
158
        );
159
    }
160
161
    /**
162
     * @param ClassMetadata $class
163
     *
164
     * @depends testEntityTableNameAndInheritance
165
     */
166
    public function testEntityUniqueConstraints($class) : ClassMetadata
167
    {
168
        self::assertCount(1, $class->table->getUniqueConstraints());
169
        self::assertEquals(
170
            [
171
                'search_idx' => [
172
                    'name'    => 'search_idx',
173
                    'columns' => ['name', 'user_email'],
174
                    'options' => [],
175
                    'flags'   => [],
176
                ],
177
            ],
178
            $class->table->getUniqueConstraints()
179
        );
180
181
        return $class;
182
    }
183
184
    /**
185
     * @param ClassMetadata $class
186
     *
187
     * @depends testEntityTableNameAndInheritance
188
     */
189
    public function testEntityOptions($class) : ClassMetadata
190
    {
191
        self::assertCount(2, $class->table->getOptions());
192
        self::assertEquals(
193
            [
194
                'foo' => 'bar',
195
                'baz' => ['key' => 'val'],
196
            ],
197
            $class->table->getOptions()
198
        );
199
200
        return $class;
201
    }
202
203
    /**
204
     * @param ClassMetadata $class
205
     *
206
     * @depends testEntityOptions
207
     */
208
    public function testEntitySequence($class) : void
209
    {
210
        $valueGenerator = $class->getProperty('id')->getValueGenerator();
0 ignored issues
show
Bug introduced by
The method getValueGenerator() does not exist on Doctrine\ORM\Mapping\Property. Did you maybe mean getValue()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

210
        $valueGenerator = $class->getProperty('id')->/** @scrutinizer ignore-call */ getValueGenerator();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
211
212
        self::assertEquals(Mapping\GeneratorType::SEQUENCE, $valueGenerator->getType(), 'Generator Type');
213
        self::assertInstanceOf(SequenceGenerator::class, $valueGenerator->getGenerator(), 'No Sequence Definition set on this driver.');
214
215
        /** @var SequenceGenerator $generator */
216
        $generator = $valueGenerator->getGenerator();
217
218
        self::assertEquals('tablename_seq', $generator->getSequenceName());
219
        self::assertEquals(100, $generator->getAllocationSize());
220
    }
221
222
    public function testEntityCustomGenerator() : void
223
    {
224
        $class          = $this->createClassMetadata(Animal::class);
225
        $valueGenerator = $class->getProperty('id')->getValueGenerator();
226
227
        self::assertEquals(Mapping\GeneratorType::CUSTOM, $valueGenerator->getType(), 'Generator Type');
228
        self::assertInstanceOf(CustomGenerator::class, $valueGenerator->getGenerator(), 'Generator Definition');
229
    }
230
231
    /**
232
     * @param ClassMetadata $class
233
     *
234
     * @depends testEntityTableNameAndInheritance
235
     */
236
    public function testProperties($class) : ClassMetadata
237
    {
238
        self::assertCount(7, $class->getPropertiesIterator());
239
240
        self::assertNotNull($class->getProperty('id'));
241
        self::assertNotNull($class->getProperty('name'));
242
        self::assertNotNull($class->getProperty('email'));
243
        self::assertNotNull($class->getProperty('version'));
244
        self::assertNotNull($class->getProperty('version'));
245
246
        return $class;
247
    }
248
249
    /**
250
     * @param ClassMetadata $class
251
     *
252
     * @depends testProperties
253
     */
254
    public function testVersionProperty($class) : void
255
    {
256
        self::assertTrue($class->isVersioned());
257
        self::assertNotNull($class->versionProperty);
258
259
        $versionPropertyName = $class->versionProperty->getName();
0 ignored issues
show
Bug introduced by
The method getName() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

259
        /** @scrutinizer ignore-call */ 
260
        $versionPropertyName = $class->versionProperty->getName();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
260
261
        self::assertEquals('version', $versionPropertyName);
262
        self::assertNotNull($class->getProperty($versionPropertyName));
263
    }
264
265
    /**
266
     * @param ClassMetadata $class
267
     *
268
     * @depends testEntityTableNameAndInheritance
269
     */
270
    public function testFieldMappingsColumnNames($class) : ClassMetadata
271
    {
272
        self::assertNotNull($class->getProperty('id'));
273
        self::assertNotNull($class->getProperty('name'));
274
        self::assertNotNull($class->getProperty('email'));
275
276
        self::assertEquals('id', $class->getProperty('id')->getColumnName());
0 ignored issues
show
Bug introduced by
The method getColumnName() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

276
        self::assertEquals('id', $class->getProperty('id')->/** @scrutinizer ignore-call */ getColumnName());
Loading history...
277
        self::assertEquals('name', $class->getProperty('name')->getColumnName());
278
        self::assertEquals('user_email', $class->getProperty('email')->getColumnName());
279
280
        return $class;
281
    }
282
283
    /**
284
     * @param ClassMetadata $class
285
     *
286
     * @depends testEntityTableNameAndInheritance
287
     */
288
    public function testStringFieldMappings($class) : ClassMetadata
289
    {
290
        self::assertNotNull($class->getProperty('name'));
291
292
        $property = $class->getProperty('name');
293
294
        self::assertEquals('string', $property->getTypeName());
0 ignored issues
show
Bug introduced by
The method getTypeName() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

294
        self::assertEquals('string', $property->/** @scrutinizer ignore-call */ getTypeName());
Loading history...
295
        self::assertEquals(50, $property->getLength());
0 ignored issues
show
Bug introduced by
The method getLength() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

295
        self::assertEquals(50, $property->/** @scrutinizer ignore-call */ getLength());
Loading history...
296
        self::assertTrue($property->isNullable());
0 ignored issues
show
Bug introduced by
The method isNullable() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

296
        self::assertTrue($property->/** @scrutinizer ignore-call */ isNullable());
Loading history...
297
        self::assertTrue($property->isUnique());
0 ignored issues
show
Bug introduced by
The method isUnique() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

297
        self::assertTrue($property->/** @scrutinizer ignore-call */ isUnique());
Loading history...
298
299
        return $class;
300
    }
301
302
    /**
303
     * @depends testEntityTableNameAndInheritance
304
     */
305
    public function testFieldOptions(ClassMetadata $class) : ClassMetadata
306
    {
307
        self::assertNotNull($class->getProperty('name'));
308
309
        $property = $class->getProperty('name');
310
        $expected = ['foo' => 'bar', 'baz' => ['key' => 'val'], 'fixed' => false];
311
312
        self::assertEquals($expected, $property->getOptions());
0 ignored issues
show
Bug introduced by
The method getOptions() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

312
        self::assertEquals($expected, $property->/** @scrutinizer ignore-call */ getOptions());
Loading history...
313
314
        return $class;
315
    }
316
317
    /**
318
     * @param ClassMetadata $class
319
     *
320
     * @depends testEntityTableNameAndInheritance
321
     */
322
    public function testIdFieldOptions($class) : ClassMetadata
323
    {
324
        self::assertNotNull($class->getProperty('id'));
325
326
        $property = $class->getProperty('id');
327
        $expected = ['foo' => 'bar', 'unsigned' => false];
328
329
        self::assertEquals($expected, $property->getOptions());
330
331
        return $class;
332
    }
333
334
    /**
335
     * @param ClassMetadata $class
336
     *
337
     * @depends testProperties
338
     */
339
    public function testIdentifier($class) : ClassMetadata
340
    {
341
        self::assertNotNull($class->getProperty('id'));
342
343
        $property = $class->getProperty('id');
344
345
        self::assertEquals('integer', $property->getTypeName());
346
        self::assertEquals(['id'], $class->identifier);
347
        self::assertEquals(
348
            Mapping\GeneratorType::SEQUENCE,
349
            $property->getValueGenerator()->getType(),
350
            'ID-Generator is not GeneratorType::AUTO'
351
        );
352
353
        return $class;
354
    }
355
356
    /**
357
     * @group #6129
358
     */
359
    public function testBooleanValuesForOptionIsSetCorrectly() : ClassMetadata
360
    {
361
        $class = $this->createClassMetadata(User::class);
362
363
        $idOptions   = $class->getProperty('id')->getOptions();
364
        $nameOptions = $class->getProperty('name')->getOptions();
365
366
        self::assertInternalType('bool', $idOptions['unsigned']);
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertInternalType() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/3369 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

366
        /** @scrutinizer ignore-deprecated */ self::assertInternalType('bool', $idOptions['unsigned']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
367
        self::assertFalse($idOptions['unsigned']);
368
        self::assertInternalType('bool', $nameOptions['fixed']);
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertInternalType() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/3369 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

368
        /** @scrutinizer ignore-deprecated */ self::assertInternalType('bool', $nameOptions['fixed']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
369
        self::assertFalse($nameOptions['fixed']);
370
371
        return $class;
372
    }
373
374
    public function testOneToOneUnidirectional() : void
375
    {
376
        // One to One owning
377
        $fullAddressClass = $this->createClassMetadata(Quote\FullAddress::class);
378
        $cityAssociation  = $fullAddressClass->getProperty('city');
379
380
        self::assertInstanceOf(Mapping\OneToOneAssociationMetadata::class, $cityAssociation);
381
        self::assertTrue($cityAssociation->isOwningSide());
382
    }
383
384
    public function testOneToOneBidirectional() : void
385
    {
386
        // One to One owning / One To One inverse
387
        $addressClass    = $this->createClassMetadata(Quote\Address::class);
388
        $userAssociation = $addressClass->getProperty('user');
389
390
        self::assertInstanceOf(Mapping\OneToOneAssociationMetadata::class, $userAssociation);
391
        self::assertTrue($userAssociation->isOwningSide());
392
393
        $userClass          = $this->createClassMetadata(Quote\User::class);
394
        $addressAssociation = $userClass->getProperty('address');
395
396
        self::assertInstanceOf(Mapping\OneToOneAssociationMetadata::class, $addressAssociation);
397
        self::assertFalse($addressAssociation->isOwningSide());
398
    }
399
400
    public function testManyToOneUnidirectional() : void
401
    {
402
        // Many to One owning
403
        $groupClass       = $this->createClassMetadata(Quote\Group::class);
404
        $groupAssociation = $groupClass->getProperty('parent');
405
406
        self::assertInstanceOf(Mapping\ManyToOneAssociationMetadata::class, $groupAssociation);
407
        self::assertTrue($groupAssociation->isOwningSide());
408
    }
409
410
    public function testManyToOneBidirectional() : void
411
    {
412
        // Many To One owning / One To Many inverse
413
        $phoneClass      = $this->createClassMetadata(Quote\Phone::class);
414
        $userAssociation = $phoneClass->getProperty('user');
415
416
        self::assertInstanceOf(Mapping\ManyToOneAssociationMetadata::class, $userAssociation);
417
        self::assertTrue($userAssociation->isOwningSide());
418
419
        $userClass        = $this->createClassMetadata(Quote\User::class);
420
        $phoneAssociation = $userClass->getProperty('phones');
421
422
        self::assertInstanceOf(Mapping\OneToManyAssociationMetadata::class, $phoneAssociation);
423
        self::assertFalse($phoneAssociation->isOwningSide());
424
    }
425
426
    public function testManyToManyBidirectional() : void
427
    {
428
        // Many to Many owning / Many to Many inverse
429
        $userClass        = $this->createClassMetadata(Quote\User::class);
430
        $groupAssociation = $userClass->getProperty('groups');
431
432
        self::assertInstanceOf(Mapping\ManyToManyAssociationMetadata::class, $groupAssociation);
433
        self::assertTrue($groupAssociation->isOwningSide());
434
435
        $groupClass      = $this->createClassMetadata(Quote\Group::class);
436
        $userAssociation = $groupClass->getProperty('users');
437
438
        self::assertInstanceOf(Mapping\ManyToManyAssociationMetadata::class, $userAssociation);
439
        self::assertFalse($userAssociation->isOwningSide());
440
    }
441
442
    /**
443
     * @param ClassMetadata $class
444
     *
445
     * @depends testProperties
446
     */
447
    public function testOwningOneToOneAssociation($class) : ClassMetadata
448
    {
449
        self::assertArrayHasKey('address', iterator_to_array($class->getPropertiesIterator()));
450
451
        $association = $class->getProperty('address');
452
453
        self::assertTrue($association->isOwningSide());
0 ignored issues
show
Bug introduced by
The method isOwningSide() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

453
        self::assertTrue($association->/** @scrutinizer ignore-call */ isOwningSide());
Loading history...
454
        self::assertEquals('user', $association->getInversedBy());
0 ignored issues
show
Bug introduced by
The method getInversedBy() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

454
        self::assertEquals('user', $association->/** @scrutinizer ignore-call */ getInversedBy());
Loading history...
455
        // Check cascading
456
        self::assertEquals(['remove'], $association->getCascade());
0 ignored issues
show
Bug introduced by
The method getCascade() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

456
        self::assertEquals(['remove'], $association->/** @scrutinizer ignore-call */ getCascade());
Loading history...
457
458
        return $class;
459
    }
460
461
    /**
462
     * @param ClassMetadata $class
463
     *
464
     * @depends testOwningOneToOneAssociation
465
     */
466
    public function testInverseOneToManyAssociation($class) : ClassMetadata
467
    {
468
        self::assertArrayHasKey('phonenumbers', iterator_to_array($class->getPropertiesIterator()));
469
470
        $association = $class->getProperty('phonenumbers');
471
472
        self::assertFalse($association->isOwningSide());
473
        self::assertTrue($association->isOrphanRemoval());
0 ignored issues
show
Bug introduced by
The method isOrphanRemoval() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

473
        self::assertTrue($association->/** @scrutinizer ignore-call */ isOrphanRemoval());
Loading history...
474
475
        // Check cascading
476
        self::assertEquals(['persist', 'remove'], $association->getCascade());
477
478
        // Test Order By
479
        self::assertEquals(['number' => 'ASC'], $association->getOrderBy());
0 ignored issues
show
Bug introduced by
The method getOrderBy() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\ToManyAssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

479
        self::assertEquals(['number' => 'ASC'], $association->/** @scrutinizer ignore-call */ getOrderBy());
Loading history...
480
481
        return $class;
482
    }
483
484
    /**
485
     * @param ClassMetadata $class
486
     *
487
     * @depends testInverseOneToManyAssociation
488
     */
489
    public function testManyToManyAssociationWithCascadeAll($class) : ClassMetadata
490
    {
491
        self::assertArrayHasKey('groups', iterator_to_array($class->getPropertiesIterator()));
492
493
        $association = $class->getProperty('groups');
494
495
        self::assertTrue($association->isOwningSide());
496
497
        // Make sure that cascade-all works as expected
498
        self::assertEquals(['remove', 'persist', 'refresh'], $association->getCascade());
499
500
        // Test Order By
501
        self::assertEquals([], $association->getOrderBy());
502
503
        return $class;
504
    }
505
506
    /**
507
     * @param ClassMetadata $class
508
     *
509
     * @depends testManyToManyAssociationWithCascadeAll
510
     */
511
    public function testLifecycleCallbacks($class) : ClassMetadata
512
    {
513
        self::assertCount(2, $class->lifecycleCallbacks);
514
        self::assertEquals($class->lifecycleCallbacks['prePersist'][0], 'doStuffOnPrePersist');
515
        self::assertEquals($class->lifecycleCallbacks['postPersist'][0], 'doStuffOnPostPersist');
516
517
        return $class;
518
    }
519
520
    /**
521
     * @param ClassMetadata $class
522
     *
523
     * @depends testManyToManyAssociationWithCascadeAll
524
     */
525
    public function testLifecycleCallbacksSupportMultipleMethodNames($class) : ClassMetadata
526
    {
527
        self::assertCount(2, $class->lifecycleCallbacks['prePersist']);
528
        self::assertEquals($class->lifecycleCallbacks['prePersist'][1], 'doOtherStuffOnPrePersistToo');
529
530
        return $class;
531
    }
532
533
    /**
534
     * @param ClassMetadata $class
535
     *
536
     * @depends testLifecycleCallbacksSupportMultipleMethodNames
537
     */
538
    public function testJoinColumnUniqueAndNullable($class) : ClassMetadata
539
    {
540
        // Non-Nullability of Join Column
541
        $association = $class->getProperty('groups');
542
        $joinTable   = $association->getJoinTable();
0 ignored issues
show
Bug introduced by
The method getJoinTable() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\ManyToManyAssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

542
        /** @scrutinizer ignore-call */ 
543
        $joinTable   = $association->getJoinTable();
Loading history...
543
        $joinColumns = $joinTable->getJoinColumns();
544
        $joinColumn  = reset($joinColumns);
545
546
        self::assertFalse($joinColumn->isNullable());
547
        self::assertFalse($joinColumn->isUnique());
548
549
        return $class;
550
    }
551
552
    /**
553
     * @param ClassMetadata $class
554
     *
555
     * @depends testJoinColumnUniqueAndNullable
556
     */
557
    public function testColumnDefinition($class) : ClassMetadata
558
    {
559
        self::assertNotNull($class->getProperty('email'));
560
561
        $property           = $class->getProperty('email');
562
        $association        = $class->getProperty('groups');
563
        $joinTable          = $association->getJoinTable();
564
        $inverseJoinColumns = $joinTable->getInverseJoinColumns();
565
        $inverseJoinColumn  = reset($inverseJoinColumns);
566
567
        self::assertEquals('CHAR(32) NOT NULL', $property->getColumnDefinition());
0 ignored issues
show
Bug introduced by
The method getColumnDefinition() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

567
        self::assertEquals('CHAR(32) NOT NULL', $property->/** @scrutinizer ignore-call */ getColumnDefinition());
Loading history...
568
        self::assertEquals('INT NULL', $inverseJoinColumn->getColumnDefinition());
569
570
        return $class;
571
    }
572
573
    /**
574
     * @param ClassMetadata $class
575
     *
576
     * @depends testColumnDefinition
577
     */
578
    public function testJoinColumnOnDelete($class) : ClassMetadata
579
    {
580
        $association = $class->getProperty('address');
581
        $joinColumns = $association->getJoinColumns();
0 ignored issues
show
Bug introduced by
The method getJoinColumns() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\ToOneAssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

581
        /** @scrutinizer ignore-call */ 
582
        $joinColumns = $association->getJoinColumns();
Loading history...
582
        $joinColumn  = reset($joinColumns);
583
584
        self::assertEquals('CASCADE', $joinColumn->getOnDelete());
585
586
        return $class;
587
    }
588
589
    /**
590
     * @group DDC-514
591
     */
592
    public function testDiscriminatorColumnDefaults() : void
593
    {
594
        if (strpos(static::class, 'PHPMappingDriver') !== false) {
595
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
596
        }
597
598
        $class = $this->createClassMetadata(Animal::class);
599
600
        self::assertNotNull($class->discriminatorColumn);
601
602
        $discrColumn = $class->discriminatorColumn;
603
604
        self::assertEquals('Animal', $discrColumn->getTableName());
605
        self::assertEquals('discr', $discrColumn->getColumnName());
606
        self::assertEquals('string', $discrColumn->getTypeName());
607
        self::assertEquals(32, $discrColumn->getLength());
608
        self::assertNull($discrColumn->getColumnDefinition());
609
    }
610
611
    /**
612
     * @group DDC-869
613
     */
614
    public function testMappedSuperclassWithRepository() : void
615
    {
616
        $em      = $this->getTestEntityManager();
617
        $factory = $this->createClassMetadataFactory($em);
618
        $class   = $factory->getMetadataFor(DDC869CreditCardPayment::class);
619
620
        self::assertNotNull($class->getProperty('id'));
621
        self::assertNotNull($class->getProperty('value'));
622
        self::assertNotNull($class->getProperty('creditCardNumber'));
623
        self::assertEquals($class->getCustomRepositoryClassName(), DDC869PaymentRepository::class);
624
        self::assertInstanceOf(DDC869PaymentRepository::class, $em->getRepository(DDC869CreditCardPayment::class));
625
        self::assertTrue($em->getRepository(DDC869ChequePayment::class)->isTrue());
0 ignored issues
show
Bug introduced by
The method isTrue() does not exist on Doctrine\Persistence\ObjectRepository. It seems like you code against a sub-type of Doctrine\Persistence\ObjectRepository such as Doctrine\ORM\EntityRepository. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

625
        self::assertTrue($em->getRepository(DDC869ChequePayment::class)->/** @scrutinizer ignore-call */ isTrue());
Loading history...
626
627
        $class = $factory->getMetadataFor(DDC869ChequePayment::class);
628
629
        self::assertNotNull($class->getProperty('id'));
630
        self::assertNotNull($class->getProperty('value'));
631
        self::assertNotNull($class->getProperty('serialNumber'));
632
        self::assertEquals($class->getCustomRepositoryClassName(), DDC869PaymentRepository::class);
633
        self::assertInstanceOf(DDC869PaymentRepository::class, $em->getRepository(DDC869ChequePayment::class));
634
        self::assertTrue($em->getRepository(DDC869ChequePayment::class)->isTrue());
635
    }
636
637
    /**
638
     * @group DDC-1476
639
     */
640
    public function testDefaultFieldType() : void
641
    {
642
        $factory = $this->createClassMetadataFactory();
643
        $class   = $factory->getMetadataFor(DDC1476EntityWithDefaultFieldType::class);
644
645
        self::assertNotNull($class->getProperty('id'));
646
        self::assertNotNull($class->getProperty('name'));
647
648
        $idProperty   = $class->getProperty('id');
649
        $nameProperty = $class->getProperty('name');
650
651
        self::assertInstanceOf(Mapping\FieldMetadata::class, $idProperty);
652
        self::assertInstanceOf(Mapping\FieldMetadata::class, $nameProperty);
653
654
        self::assertEquals('string', $idProperty->getTypeName());
655
        self::assertEquals('string', $nameProperty->getTypeName());
656
657
        self::assertEquals('id', $idProperty->getName());
658
        self::assertEquals('name', $nameProperty->getName());
659
660
        self::assertEquals('id', $idProperty->getColumnName());
661
        self::assertEquals('name', $nameProperty->getColumnName());
662
663
        self::assertFalse($idProperty->hasValueGenerator());
0 ignored issues
show
Bug introduced by
The method hasValueGenerator() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

663
        self::assertFalse($idProperty->/** @scrutinizer ignore-call */ hasValueGenerator());
Loading history...
664
    }
665
666
    /**
667
     * @group DDC-1170
668
     */
669
    public function testIdentifierColumnDefinition() : void
670
    {
671
        $class = $this->createClassMetadata(DDC1170Entity::class);
672
673
        self::assertNotNull($class->getProperty('id'));
674
        self::assertNotNull($class->getProperty('value'));
675
676
        self::assertEquals('INT unsigned NOT NULL', $class->getProperty('id')->getColumnDefinition());
677
        self::assertEquals('VARCHAR(255) NOT NULL', $class->getProperty('value')->getColumnDefinition());
678
    }
679
680
    /**
681
     * @group DDC-559
682
     */
683
    public function testNamingStrategy() : void
684
    {
685
        $em      = $this->getTestEntityManager();
686
        $factory = $this->createClassMetadataFactory($em);
687
688
        self::assertInstanceOf(DefaultNamingStrategy::class, $em->getConfiguration()->getNamingStrategy());
689
        $em->getConfiguration()->setNamingStrategy(new UnderscoreNamingStrategy(CASE_UPPER));
690
        self::assertInstanceOf(UnderscoreNamingStrategy::class, $em->getConfiguration()->getNamingStrategy());
691
692
        $class        = $factory->getMetadataFor(DDC1476EntityWithDefaultFieldType::class);
693
        $idProperty   = $class->getProperty('id');
694
        $nameProperty = $class->getProperty('name');
695
696
        self::assertEquals('ID', $idProperty->getColumnName());
697
        self::assertEquals('NAME', $nameProperty->getColumnName());
698
        self::assertEquals('DDC1476ENTITY_WITH_DEFAULT_FIELD_TYPE', $class->table->getName());
699
    }
700
701
    /**
702
     * @group DDC-807
703
     * @group DDC-553
704
     */
705
    public function testDiscriminatorColumnDefinition() : void
706
    {
707
        $class = $this->createClassMetadata(DDC807Entity::class);
708
709
        self::assertNotNull($class->discriminatorColumn);
710
711
        $discrColumn = $class->discriminatorColumn;
712
713
        self::assertEquals('dtype', $discrColumn->getColumnName());
714
        self::assertEquals("ENUM('ONE','TWO')", $discrColumn->getColumnDefinition());
715
    }
716
717
    /**
718
     * @group DDC-889
719
     */
720
    public function testInvalidEntityOrMappedSuperClassShouldMentionParentClasses() : void
721
    {
722
        $this->expectException(MappingException::class);
723
        $this->expectExceptionMessage('Class "Doctrine\Tests\Models\DDC889\DDC889Class" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass" is not a valid entity or mapped super class.');
724
725
        $this->createClassMetadata(DDC889Class::class);
726
    }
727
728
    /**
729
     * @group DDC-889
730
     */
731
    public function testIdentifierRequiredShouldMentionParentClasses() : void
732
    {
733
        $factory = $this->createClassMetadataFactory();
734
735
        $this->expectException(MappingException::class);
736
        $this->expectExceptionMessage('No identifier/primary key specified for Entity "Doctrine\Tests\Models\DDC889\DDC889Entity" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass". Every Entity must have an identifier/primary key.');
737
738
        $factory->getMetadataFor(DDC889Entity::class);
739
    }
740
741
    /**
742
     * @group DDC-964
743
     */
744
    public function testAssociationOverridesMapping() : void
745
    {
746
        $factory       = $this->createClassMetadataFactory();
747
        $adminMetadata = $factory->getMetadataFor(DDC964Admin::class);
748
        $guestMetadata = $factory->getMetadataFor(DDC964Guest::class);
749
750
        // assert groups association mappings
751
        self::assertArrayHasKey('groups', iterator_to_array($guestMetadata->getPropertiesIterator()));
752
        self::assertArrayHasKey('groups', iterator_to_array($adminMetadata->getPropertiesIterator()));
753
754
        $guestGroups = $guestMetadata->getProperty('groups');
755
        $adminGroups = $adminMetadata->getProperty('groups');
756
757
        // assert not override attributes
758
        self::assertEquals($guestGroups->getName(), $adminGroups->getName());
759
        self::assertEquals(get_class($guestGroups), get_class($adminGroups));
760
        self::assertEquals($guestGroups->getMappedBy(), $adminGroups->getMappedBy());
0 ignored issues
show
Bug introduced by
The method getMappedBy() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

760
        self::assertEquals($guestGroups->/** @scrutinizer ignore-call */ getMappedBy(), $adminGroups->getMappedBy());
Loading history...
761
        self::assertEquals($guestGroups->getInversedBy(), $adminGroups->getInversedBy());
762
        self::assertEquals($guestGroups->isOwningSide(), $adminGroups->isOwningSide());
763
        self::assertEquals($guestGroups->getFetchMode(), $adminGroups->getFetchMode());
0 ignored issues
show
Bug introduced by
The method getFetchMode() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

763
        self::assertEquals($guestGroups->/** @scrutinizer ignore-call */ getFetchMode(), $adminGroups->getFetchMode());
Loading history...
764
        self::assertEquals($guestGroups->getCascade(), $adminGroups->getCascade());
765
766
        // assert not override attributes
767
        $guestGroupsJoinTable          = $guestGroups->getJoinTable();
768
        $guestGroupsJoinColumns        = $guestGroupsJoinTable->getJoinColumns();
769
        $guestGroupsJoinColumn         = reset($guestGroupsJoinColumns);
770
        $guestGroupsInverseJoinColumns = $guestGroupsJoinTable->getInverseJoinColumns();
771
        $guestGroupsInverseJoinColumn  = reset($guestGroupsInverseJoinColumns);
772
773
        self::assertEquals('ddc964_users_groups', $guestGroupsJoinTable->getName());
774
        self::assertEquals('user_id', $guestGroupsJoinColumn->getColumnName());
775
        self::assertEquals('group_id', $guestGroupsInverseJoinColumn->getColumnName());
776
777
        $adminGroupsJoinTable          = $adminGroups->getJoinTable();
778
        $adminGroupsJoinColumns        = $adminGroupsJoinTable->getJoinColumns();
779
        $adminGroupsJoinColumn         = reset($adminGroupsJoinColumns);
780
        $adminGroupsInverseJoinColumns = $adminGroupsJoinTable->getInverseJoinColumns();
781
        $adminGroupsInverseJoinColumn  = reset($adminGroupsInverseJoinColumns);
782
783
        self::assertEquals('ddc964_users_admingroups', $adminGroupsJoinTable->getName());
784
        self::assertEquals('adminuser_id', $adminGroupsJoinColumn->getColumnName());
785
        self::assertEquals('admingroup_id', $adminGroupsInverseJoinColumn->getColumnName());
786
787
        // assert address association mappings
788
        self::assertArrayHasKey('address', iterator_to_array($guestMetadata->getPropertiesIterator()));
789
        self::assertArrayHasKey('address', iterator_to_array($adminMetadata->getPropertiesIterator()));
790
791
        $guestAddress = $guestMetadata->getProperty('address');
792
        $adminAddress = $adminMetadata->getProperty('address');
793
794
        // assert not override attributes
795
        self::assertEquals($guestAddress->getName(), $adminAddress->getName());
796
        self::assertEquals(get_class($guestAddress), get_class($adminAddress));
797
        self::assertEquals($guestAddress->getMappedBy(), $adminAddress->getMappedBy());
798
        self::assertEquals($guestAddress->getInversedBy(), $adminAddress->getInversedBy());
799
        self::assertEquals($guestAddress->isOwningSide(), $adminAddress->isOwningSide());
800
        self::assertEquals($guestAddress->getFetchMode(), $adminAddress->getFetchMode());
801
        self::assertEquals($guestAddress->getCascade(), $adminAddress->getCascade());
802
803
        // assert override
804
        $guestAddressJoinColumns = $guestAddress->getJoinColumns();
805
        $guestAddressJoinColumn  = reset($guestAddressJoinColumns);
806
807
        self::assertEquals('address_id', $guestAddressJoinColumn->getColumnName());
808
809
        $adminAddressJoinColumns = $adminAddress->getJoinColumns();
810
        $adminAddressJoinColumn  = reset($adminAddressJoinColumns);
811
812
        self::assertEquals('adminaddress_id', $adminAddressJoinColumn->getColumnName());
813
    }
814
815
    /**
816
     * @group DDC-3579
817
     */
818
    public function testInversedByOverrideMapping() : void
819
    {
820
        $factory       = $this->createClassMetadataFactory();
821
        $adminMetadata = $factory->getMetadataFor(DDC3579Admin::class);
822
823
        // assert groups association mappings
824
        self::assertArrayHasKey('groups', iterator_to_array($adminMetadata->getPropertiesIterator()));
825
826
        $adminGroups = $adminMetadata->getProperty('groups');
827
828
        // assert override
829
        self::assertEquals('admins', $adminGroups->getInversedBy());
830
    }
831
832
    /**
833
     * @group DDC-5934
834
     */
835
    public function testFetchOverrideMapping() : void
836
    {
837
        // check override metadata
838
        $contractMetadata = $this->createClassMetadataFactory()->getMetadataFor(DDC5934Contract::class);
839
840
        self::assertArrayHasKey('members', iterator_to_array($contractMetadata->getPropertiesIterator()));
841
842
        $contractMembers = $contractMetadata->getProperty('members');
843
844
        self::assertSame(Mapping\FetchMode::EXTRA_LAZY, $contractMembers->getFetchMode());
845
    }
846
847
    /**
848
     * @group DDC-964
849
     */
850
    public function testAttributeOverridesMapping() : void
851
    {
852
        $factory       = $this->createClassMetadataFactory();
853
        $adminMetadata = $factory->getMetadataFor(DDC964Admin::class);
854
855
        self::assertEquals(
856
            [
857
                'user_id' => 'id',
858
                'user_name' => 'name',
859
                'adminaddress_id' => 'address',
860
            ],
861
            $adminMetadata->fieldNames
862
        );
863
864
        self::assertNotNull($adminMetadata->getProperty('id'));
865
866
        $idProperty = $adminMetadata->getProperty('id');
867
868
        self::assertTrue($idProperty->isPrimaryKey());
869
        self::assertEquals('id', $idProperty->getName());
870
        self::assertEquals('user_id', $idProperty->getColumnName());
871
872
        self::assertNotNull($adminMetadata->getProperty('name'));
873
874
        $nameProperty = $adminMetadata->getProperty('name');
875
876
        self::assertEquals('name', $nameProperty->getName());
877
        self::assertEquals('user_name', $nameProperty->getColumnName());
878
        self::assertEquals(250, $nameProperty->getLength());
879
        self::assertTrue($nameProperty->isNullable());
880
        self::assertFalse($nameProperty->isUnique());
881
882
        $guestMetadata = $factory->getMetadataFor(DDC964Guest::class);
883
884
        self::assertEquals(
885
            [
886
                'guest_id' => 'id',
887
                'guest_name' => 'name',
888
                'address_id' => 'address',
889
            ],
890
            $guestMetadata->fieldNames
891
        );
892
893
        self::assertNotNull($guestMetadata->getProperty('id'));
894
895
        $idProperty = $guestMetadata->getProperty('id');
896
897
        self::assertTrue($idProperty->isPrimaryKey());
898
        self::assertEquals('id', $idProperty->getName());
899
        self::assertEquals('guest_id', $idProperty->getColumnName());
900
901
        self::assertNotNull($guestMetadata->getProperty('name'));
902
903
        $nameProperty = $guestMetadata->getProperty('name');
904
905
        self::assertEquals('name', $nameProperty->getName());
906
        self::assertEquals('guest_name', $nameProperty->getColumnName());
907
        self::assertEquals(240, $nameProperty->getLength());
908
        self::assertFalse($nameProperty->isNullable());
909
        self::assertTrue($nameProperty->isUnique());
910
    }
911
912
    /**
913
     * @group DDC-1955
914
     */
915
    public function testEntityListeners() : void
916
    {
917
        $factory    = $this->createClassMetadataFactory();
918
        $superClass = $factory->getMetadataFor(CompanyContract::class);
919
        $flexClass  = $factory->getMetadataFor(CompanyFixContract::class);
920
        $fixClass   = $factory->getMetadataFor(CompanyFlexContract::class);
921
922
        self::assertArrayHasKey(Events::prePersist, $superClass->entityListeners);
923
        self::assertArrayHasKey(Events::postPersist, $superClass->entityListeners);
924
925
        self::assertCount(1, $superClass->entityListeners[Events::prePersist]);
926
        self::assertCount(1, $superClass->entityListeners[Events::postPersist]);
927
928
        $postPersist = $superClass->entityListeners[Events::postPersist][0];
929
        $prePersist  = $superClass->entityListeners[Events::prePersist][0];
930
931
        self::assertEquals(CompanyContractListener::class, $postPersist['class']);
932
        self::assertEquals(CompanyContractListener::class, $prePersist['class']);
933
        self::assertEquals('postPersistHandler', $postPersist['method']);
934
        self::assertEquals('prePersistHandler', $prePersist['method']);
935
936
        //Inherited listeners
937
        self::assertEquals($fixClass->entityListeners, $superClass->entityListeners);
938
        self::assertEquals($flexClass->entityListeners, $superClass->entityListeners);
939
    }
940
941
    /**
942
     * @group DDC-1955
943
     */
944
    public function testEntityListenersOverride() : void
945
    {
946
        $factory    = $this->createClassMetadataFactory();
947
        $ultraClass = $factory->getMetadataFor(CompanyFlexUltraContract::class);
948
949
        //overridden listeners
950
        self::assertArrayHasKey(Events::postPersist, $ultraClass->entityListeners);
951
        self::assertArrayHasKey(Events::prePersist, $ultraClass->entityListeners);
952
953
        self::assertCount(1, $ultraClass->entityListeners[Events::postPersist]);
954
        self::assertCount(3, $ultraClass->entityListeners[Events::prePersist]);
955
956
        $postPersist = $ultraClass->entityListeners[Events::postPersist][0];
957
        $prePersist  = $ultraClass->entityListeners[Events::prePersist][0];
958
959
        self::assertEquals(CompanyContractListener::class, $postPersist['class']);
960
        self::assertEquals(CompanyContractListener::class, $prePersist['class']);
961
        self::assertEquals('postPersistHandler', $postPersist['method']);
962
        self::assertEquals('prePersistHandler', $prePersist['method']);
963
964
        $prePersist = $ultraClass->entityListeners[Events::prePersist][1];
965
        self::assertEquals(CompanyFlexUltraContractListener::class, $prePersist['class']);
966
        self::assertEquals('prePersistHandler1', $prePersist['method']);
967
968
        $prePersist = $ultraClass->entityListeners[Events::prePersist][2];
969
        self::assertEquals(CompanyFlexUltraContractListener::class, $prePersist['class']);
970
        self::assertEquals('prePersistHandler2', $prePersist['method']);
971
    }
972
973
    /**
974
     * @group DDC-2183
975
     */
976
    public function testSecondLevelCacheMapping() : void
977
    {
978
        $factory = $this->createClassMetadataFactory();
979
        $class   = $factory->getMetadataFor(City::class);
980
981
        self::assertNotNull($class->getCache());
982
        self::assertEquals(Mapping\CacheUsage::READ_ONLY, $class->getCache()->getUsage());
983
        self::assertEquals('doctrine_tests_models_cache_city', $class->getCache()->getRegion());
984
985
        self::assertArrayHasKey('state', iterator_to_array($class->getPropertiesIterator()));
986
987
        $stateAssociation = $class->getProperty('state');
988
989
        self::assertNotNull($stateAssociation->getCache());
0 ignored issues
show
Bug introduced by
The method getCache() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

989
        self::assertNotNull($stateAssociation->/** @scrutinizer ignore-call */ getCache());
Loading history...
990
        self::assertEquals(Mapping\CacheUsage::READ_ONLY, $stateAssociation->getCache()->getUsage());
991
        self::assertEquals('doctrine_tests_models_cache_city__state', $stateAssociation->getCache()->getRegion());
992
993
        self::assertArrayHasKey('attractions', iterator_to_array($class->getPropertiesIterator()));
994
995
        $attractionsAssociation = $class->getProperty('attractions');
996
997
        self::assertNotNull($attractionsAssociation->getCache());
998
        self::assertEquals(Mapping\CacheUsage::READ_ONLY, $attractionsAssociation->getCache()->getUsage());
999
        self::assertEquals('doctrine_tests_models_cache_city__attractions', $attractionsAssociation->getCache()->getRegion());
1000
    }
1001
1002
    /**
1003
     * @group DDC-2825
1004
     * @group 881
1005
     */
1006
    public function testSchemaDefinitionViaExplicitTableSchemaAnnotationProperty() : void
1007
    {
1008
        $factory  = $this->createClassMetadataFactory();
1009
        $metadata = $factory->getMetadataFor(ExplicitSchemaAndTable::class);
1010
1011
        self::assertSame('explicit_schema', $metadata->getSchemaName());
1012
        self::assertSame('explicit_table', $metadata->getTableName());
1013
    }
1014
1015
    /**
1016
     * @group DDC-2825
1017
     * @group 881
1018
     */
1019
    public function testSchemaDefinitionViaSchemaDefinedInTableNameInTableAnnotationProperty() : void
1020
    {
1021
        $factory  = $this->createClassMetadataFactory();
1022
        $metadata = $factory->getMetadataFor(SchemaAndTableInTableName::class);
1023
1024
        self::assertSame('implicit_schema', $metadata->getSchemaName());
1025
        self::assertSame('implicit_table', $metadata->getTableName());
1026
    }
1027
1028
    /**
1029
     * @group DDC-514
1030
     * @group DDC-1015
1031
     */
1032
    public function testDiscriminatorColumnDefaultLength() : void
1033
    {
1034
        if (strpos(static::class, 'PHPMappingDriver') !== false) {
1035
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1036
        }
1037
1038
        $class = $this->createClassMetadata(SingleTableEntityNoDiscriminatorColumnMapping::class);
1039
1040
        self::assertEquals(255, $class->discriminatorColumn->getLength());
1041
1042
        $class = $this->createClassMetadata(SingleTableEntityIncompleteDiscriminatorColumnMapping::class);
1043
1044
        self::assertEquals(255, $class->discriminatorColumn->getLength());
1045
    }
1046
1047
    /**
1048
     * @group DDC-514
1049
     * @group DDC-1015
1050
     */
1051
    public function testDiscriminatorColumnDefaultType() : void
1052
    {
1053
        if (strpos(static::class, 'PHPMappingDriver') !== false) {
1054
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1055
        }
1056
1057
        $class = $this->createClassMetadata(SingleTableEntityNoDiscriminatorColumnMapping::class);
1058
1059
        self::assertEquals('string', $class->discriminatorColumn->getTypeName());
1060
1061
        $class = $this->createClassMetadata(SingleTableEntityIncompleteDiscriminatorColumnMapping::class);
1062
1063
        self::assertEquals('string', $class->discriminatorColumn->getTypeName());
1064
    }
1065
1066
    /**
1067
     * @group DDC-514
1068
     * @group DDC-1015
1069
     */
1070
    public function testDiscriminatorColumnDefaultName() : void
1071
    {
1072
        if (strpos(static::class, 'PHPMappingDriver') !== false) {
1073
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1074
        }
1075
1076
        $class = $this->createClassMetadata(SingleTableEntityNoDiscriminatorColumnMapping::class);
1077
1078
        self::assertEquals('dtype', $class->discriminatorColumn->getColumnName());
1079
1080
        $class = $this->createClassMetadata(SingleTableEntityIncompleteDiscriminatorColumnMapping::class);
1081
1082
        self::assertEquals('dtype', $class->discriminatorColumn->getColumnName());
1083
    }
1084
}
1085
1086
/**
1087
 * @ORM\Entity
1088
 * @ORM\HasLifecycleCallbacks
1089
 * @ORM\Table(
1090
 *  name="cms_users",
1091
 *  uniqueConstraints={@ORM\UniqueConstraint(name="search_idx", columns={"name", "user_email"})},
1092
 *  indexes={@ORM\Index(name="name_idx", columns={"name"}), @ORM\Index(columns={"user_email"})},
1093
 *  options={"foo": "bar", "baz": {"key": "val"}}
1094
 * )
1095
 */
1096
class User
1097
{
1098
    /**
1099
     * @ORM\Id
1100
     * @ORM\Column(type="integer", options={"foo": "bar", "unsigned": false})
1101
     * @ORM\GeneratedValue(strategy="AUTO")
1102
     * @ORM\SequenceGenerator(sequenceName="tablename_seq", allocationSize=100)
1103
     */
1104
    public $id;
1105
1106
    /** @ORM\Column(length=50, nullable=true, unique=true, options={"foo": "bar", "baz": {"key": "val"}, "fixed": false}) */
1107
    public $name;
1108
1109
    /** @ORM\Column(name="user_email", columnDefinition="CHAR(32) NOT NULL") */
1110
    public $email;
1111
1112
    /**
1113
     * @ORM\OneToOne(targetEntity=Address::class, cascade={"remove"}, inversedBy="user")
1114
     * @ORM\JoinColumn(onDelete="CASCADE")
1115
     */
1116
    public $address;
1117
1118
    /**
1119
     * @ORM\OneToMany(targetEntity=Phonenumber::class, mappedBy="user", cascade={"persist"}, orphanRemoval=true)
1120
     * @ORM\OrderBy({"number"="ASC"})
1121
     */
1122
    public $phonenumbers;
1123
1124
    /**
1125
     * @ORM\ManyToMany(targetEntity=Group::class, cascade={"all"})
1126
     * @ORM\JoinTable(name="cms_user_groups",
1127
     *    joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false, unique=false)},
1128
     *    inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id", columnDefinition="INT NULL")}
1129
     * )
1130
     */
1131
    public $groups;
1132
1133
    /**
1134
     * @ORM\Column(type="integer")
1135
     * @ORM\Version
1136
     */
1137
    public $version;
1138
1139
    /**
1140
     * @ORM\PrePersist
1141
     */
1142
    public function doStuffOnPrePersist()
1143
    {
1144
    }
1145
1146
    /**
1147
     * @ORM\PrePersist
1148
     */
1149
    public function doOtherStuffOnPrePersistToo()
1150
    {
1151
    }
1152
1153
    /**
1154
     * @ORM\PostPersist
1155
     */
1156
    public function doStuffOnPostPersist()
1157
    {
1158
    }
1159
1160
    public static function loadMetadata(ClassMetadata $metadata)
1161
    {
1162
        $tableMetadata = new Mapping\TableMetadata();
1163
1164
        $tableMetadata->setName('cms_users');
1165
        $tableMetadata->addIndex(
1166
            [
1167
                'name'    => 'name_idx',
1168
                'columns' => ['name'],
1169
                'unique'  => false,
1170
                'options' => [],
1171
                'flags'   => [],
1172
            ]
1173
        );
1174
1175
        $tableMetadata->addIndex(
1176
            [
1177
                'name'    => null,
1178
                'columns' => ['user_email'],
1179
                'unique'  => false,
1180
                'options' => [],
1181
                'flags'   => [],
1182
            ]
1183
        );
1184
1185
        $tableMetadata->addUniqueConstraint(
1186
            [
1187
                'name'    => 'search_idx',
1188
                'columns' => ['name', 'user_email'],
1189
                'options' => [],
1190
                'flags'   => [],
1191
            ]
1192
        );
1193
        $tableMetadata->addOption('foo', 'bar');
1194
        $tableMetadata->addOption('baz', ['key' => 'val']);
1195
1196
        $metadata->setTable($tableMetadata);
1197
        $metadata->setInheritanceType(Mapping\InheritanceType::NONE);
0 ignored issues
show
Bug introduced by
Doctrine\ORM\Mapping\InheritanceType::NONE of type string is incompatible with the type integer expected by parameter $type of Doctrine\ORM\Mapping\Cla...a::setInheritanceType(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1197
        $metadata->setInheritanceType(/** @scrutinizer ignore-type */ Mapping\InheritanceType::NONE);
Loading history...
1198
        $metadata->setChangeTrackingPolicy(Mapping\ChangeTrackingPolicy::DEFERRED_IMPLICIT);
1199
1200
        $metadata->addLifecycleCallback('prePersist', 'doStuffOnPrePersist');
1201
        $metadata->addLifecycleCallback('prePersist', 'doOtherStuffOnPrePersistToo');
1202
        $metadata->addLifecycleCallback('postPersist', 'doStuffOnPostPersist');
1203
1204
        $metadata->setGeneratorDefinition(
0 ignored issues
show
Bug introduced by
The method setGeneratorDefinition() does not exist on Doctrine\ORM\Mapping\ClassMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1204
        $metadata->/** @scrutinizer ignore-call */ 
1205
                   setGeneratorDefinition(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1205
            [
1206
                'sequenceName'   => 'tablename_seq',
1207
                'allocationSize' => 100,
1208
            ]
1209
        );
1210
1211
        $fieldMetadata = new Mapping\FieldMetadata('id');
1212
        $fieldMetadata->setType(Type::getType('integer'));
1213
        $fieldMetadata->setPrimaryKey(true);
1214
        $fieldMetadata->setOptions(['foo' => 'bar', 'unsigned' => false]);
1215
1216
        $metadata->addProperty($fieldMetadata);
1217
1218
        $fieldMetadata = new Mapping\FieldMetadata('name');
1219
        $fieldMetadata->setType(Type::getType('string'));
1220
        $fieldMetadata->setLength(50);
1221
        $fieldMetadata->setNullable(true);
1222
        $fieldMetadata->setUnique(true);
1223
        $fieldMetadata->setOptions(
1224
            [
1225
                'foo' => 'bar',
1226
                'baz' => ['key' => 'val'],
1227
                'fixed' => false,
1228
            ]
1229
        );
1230
1231
        $metadata->addProperty($fieldMetadata);
1232
1233
        $fieldMetadata = new Mapping\FieldMetadata('email');
1234
1235
        $fieldMetadata->setType(Type::getType('string'));
1236
        $fieldMetadata->setColumnName('user_email');
1237
        $fieldMetadata->setColumnDefinition('CHAR(32) NOT NULL');
1238
1239
        $metadata->addProperty($fieldMetadata);
1240
1241
        $fieldMetadata = new Mapping\FieldMetadata('version');
1242
1243
        $fieldMetadata->setType(Type::getType('integer'));
1244
        $fieldMetadata->setVersioned(true);
1245
1246
        $metadata->addProperty($fieldMetadata);
1247
        $metadata->setIdGeneratorType(Mapping\GeneratorType::AUTO);
0 ignored issues
show
Bug introduced by
The method setIdGeneratorType() does not exist on Doctrine\ORM\Mapping\ClassMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1247
        $metadata->/** @scrutinizer ignore-call */ 
1248
                   setIdGeneratorType(Mapping\GeneratorType::AUTO);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1248
1249
        $joinColumns = [];
1250
1251
        $joinColumn = new Mapping\JoinColumnMetadata();
1252
1253
        $joinColumn->setColumnName('address_id');
1254
        $joinColumn->setReferencedColumnName('id');
1255
        $joinColumn->setOnDelete('CASCADE');
1256
1257
        $joinColumns[] = $joinColumn;
1258
1259
        $association = new Mapping\OneToOneAssociationMetadata('address');
1260
1261
        $association->setJoinColumns($joinColumns);
1262
        $association->setTargetEntity(Address::class);
1263
        $association->setInversedBy('user');
1264
        $association->setCascade(['remove']);
1265
        $association->setOrphanRemoval(false);
1266
1267
        $metadata->addProperty($association);
1268
1269
        $association = new Mapping\OneToManyAssociationMetadata('phonenumbers');
1270
1271
        $association->setTargetEntity(Phonenumber::class);
1272
        $association->setMappedBy('user');
1273
        $association->setCascade(['persist']);
1274
        $association->setOrderBy(['number' => 'ASC']);
1275
        $association->setOrphanRemoval(true);
1276
1277
        $metadata->addProperty($association);
1278
1279
        $joinTable = new Mapping\JoinTableMetadata();
1280
        $joinTable->setName('cms_users_groups');
1281
1282
        $joinColumn = new Mapping\JoinColumnMetadata();
1283
1284
        $joinColumn->setColumnName('user_id');
1285
        $joinColumn->setReferencedColumnName('id');
1286
        $joinColumn->setNullable(false);
1287
        $joinColumn->setUnique(false);
1288
1289
        $joinTable->addJoinColumn($joinColumn);
1290
1291
        $joinColumn = new Mapping\JoinColumnMetadata();
1292
1293
        $joinColumn->setColumnName('group_id');
1294
        $joinColumn->setReferencedColumnName('id');
1295
        $joinColumn->setColumnDefinition('INT NULL');
1296
1297
        $joinTable->addInverseJoinColumn($joinColumn);
1298
1299
        $association = new Mapping\ManyToManyAssociationMetadata('groups');
1300
1301
        $association->setJoinTable($joinTable);
1302
        $association->setTargetEntity(Group::class);
1303
        $association->setCascade(['remove', 'persist', 'refresh']);
1304
1305
        $metadata->addProperty($association);
1306
    }
1307
}
1308
1309
class CustomGenerator implements Generator
1310
{
1311
    public function generate(EntityManagerInterface $em, ?object $entity)
1312
    {
1313
        // TODO: Implement generate() method.
1314
    }
1315
1316
    public function isPostInsertGenerator() : bool
1317
    {
1318
        return false;
1319
    }
1320
}
1321
1322
/**
1323
 * @ORM\Entity
1324
 * @ORM\InheritanceType("SINGLE_TABLE")
1325
 * @ORM\DiscriminatorMap({"cat" = Cat::class, "dog" = Dog::class})
1326
 * @ORM\DiscriminatorColumn(name="discr", length=32, type="string")
1327
 */
1328
abstract class Animal
1329
{
1330
    /**
1331
     * @ORM\Id @ORM\Column(type="string") @ORM\GeneratedValue(strategy="CUSTOM")
1332
     * @ORM\CustomIdGenerator(class=CustomGenerator::class)
1333
     */
1334
    public $id;
1335
}
1336
1337
/** @ORM\Entity */
1338
class Cat extends Animal
1339
{
1340
}
1341
1342
/** @ORM\Entity */
1343
class Dog extends Animal
1344
{
1345
}
1346
1347
/**
1348
 * @ORM\Entity
1349
 */
1350
class DDC1170Entity
1351
{
1352
    /**
1353
     * @param string $value
1354
     */
1355
    public function __construct($value = null)
1356
    {
1357
        $this->value = $value;
1358
    }
1359
1360
    /**
1361
     * @ORM\Id
1362
     * @ORM\GeneratedValue(strategy="NONE")
1363
     * @ORM\Column(type="integer", columnDefinition = "INT unsigned NOT NULL")
1364
     */
1365
    private $id;
1366
1367
    /** @ORM\Column(columnDefinition = "VARCHAR(255) NOT NULL") */
1368
    private $value;
1369
1370
    /**
1371
     * @return int
1372
     */
1373
    public function getId()
1374
    {
1375
        return $this->id;
1376
    }
1377
1378
    /**
1379
     * @return string
1380
     */
1381
    public function getValue()
1382
    {
1383
        return $this->value;
1384
    }
1385
}
1386
1387
/**
1388
 * @ORM\Entity
1389
 * @ORM\InheritanceType("SINGLE_TABLE")
1390
 * @ORM\DiscriminatorMap({"ONE" = DDC807SubClasse1::class, "TWO" = DDC807SubClasse2::class})
1391
 * @ORM\DiscriminatorColumn(name = "dtype", columnDefinition="ENUM('ONE','TWO')")
1392
 */
1393
class DDC807Entity
1394
{
1395
    /**
1396
     * @ORM\Id
1397
     * @ORM\Column(type="integer")
1398
     * @ORM\GeneratedValue(strategy="NONE")
1399
     */
1400
    public $id;
1401
}
1402
1403
class DDC807SubClasse1
1404
{
1405
}
1406
class DDC807SubClasse2
1407
{
1408
}
1409
1410
class Address
1411
{
1412
}
1413
class Phonenumber
1414
{
1415
}
1416
class Group
1417
{
1418
}
1419
1420
/**
1421
 * @ORM\Entity
1422
 * @ORM\Table(indexes={@ORM\Index(columns={"content"}, flags={"fulltext"}, options={"where": "content IS NOT NULL"})})
1423
 */
1424
class Comment
1425
{
1426
    /** @ORM\Column(type="text") */
1427
    private $content;
0 ignored issues
show
introduced by
The private property $content is not used, and could be removed.
Loading history...
1428
}
1429
1430
/**
1431
 * @ORM\Entity
1432
 * @ORM\InheritanceType("SINGLE_TABLE")
1433
 * @ORM\DiscriminatorMap({
1434
 *     "ONE" = Doctrine\Tests\ORM\Mapping\SingleTableEntityNoDiscriminatorColumnMappingSub1::class,
1435
 *     "TWO" = Doctrine\Tests\ORM\Mapping\SingleTableEntityNoDiscriminatorColumnMappingSub2::class
1436
 * })
1437
 */
1438
class SingleTableEntityNoDiscriminatorColumnMapping
1439
{
1440
    /**
1441
     * @ORM\Id
1442
     * @ORM\Column(type="integer")
1443
     * @ORM\GeneratedValue(strategy="NONE")
1444
     */
1445
    public $id;
1446
}
1447
1448
/**
1449
 * @ORM\Entity
1450
 */
1451
class SingleTableEntityNoDiscriminatorColumnMappingSub1 extends SingleTableEntityNoDiscriminatorColumnMapping
1452
{
1453
}
1454
1455
/**
1456
 * @ORM\Entity
1457
 */
1458
class SingleTableEntityNoDiscriminatorColumnMappingSub2 extends SingleTableEntityNoDiscriminatorColumnMapping
1459
{
1460
}
1461
1462
/**
1463
 * @ORM\Entity
1464
 * @ORM\InheritanceType("SINGLE_TABLE")
1465
 * @ORM\DiscriminatorMap({
1466
 *     "ONE" = Doctrine\Tests\ORM\Mapping\SingleTableEntityIncompleteDiscriminatorColumnMappingSub1::class,
1467
 *     "TWO" = Doctrine\Tests\ORM\Mapping\SingleTableEntityIncompleteDiscriminatorColumnMappingSub2::class
1468
 * })
1469
 * @ORM\DiscriminatorColumn(name="dtype")
1470
 */
1471
class SingleTableEntityIncompleteDiscriminatorColumnMapping
1472
{
1473
    /**
1474
     * @ORM\Id
1475
     * @ORM\Column(type="integer")
1476
     * @ORM\GeneratedValue(strategy="NONE")
1477
     */
1478
    public $id;
1479
}
1480
1481
class SingleTableEntityIncompleteDiscriminatorColumnMappingSub1 extends SingleTableEntityIncompleteDiscriminatorColumnMapping
1482
{
1483
}
1484
1485
class SingleTableEntityIncompleteDiscriminatorColumnMappingSub2 extends SingleTableEntityIncompleteDiscriminatorColumnMapping
1486
{
1487
}
1488