25
25
import org .hibernate .internal .DynamicFilterAliasGenerator ;
26
26
import org .hibernate .internal .FilterAliasGenerator ;
27
27
import org .hibernate .internal .util .MarkerObject ;
28
+ import org .hibernate .internal .util .ReflectHelper ;
28
29
import org .hibernate .internal .util .StringHelper ;
29
30
import org .hibernate .internal .util .collections .ArrayHelper ;
30
31
import org .hibernate .internal .util .collections .CollectionHelper ;
@@ -128,6 +129,9 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
128
129
//private final Map propertyTableNumbersByName = new HashMap();
129
130
// private final Map<String, Integer> propertyTableNumbersByNameAndSubclass;
130
131
132
+ private final String [] fullDiscriminatorSQLValues ;
133
+ private final Object [] fullDiscriminatorValues ;
134
+
131
135
private static final Object NULL_DISCRIMINATOR = new MarkerObject ( "<null discriminator>" );
132
136
private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject ( "<not null discriminator>" );
133
137
@@ -293,7 +297,7 @@ public SingleTableEntityPersister(
293
297
// DISCRIMINATOR
294
298
295
299
if ( persistentClass .isPolymorphic () ) {
296
- Value discrimValue = persistentClass .getDiscriminator ();
300
+ final Value discrimValue = persistentClass .getDiscriminator ();
297
301
if ( discrimValue == null ) {
298
302
throw new MappingException ( "discriminator mapping required for single table polymorphic persistence" );
299
303
}
@@ -318,37 +322,10 @@ public SingleTableEntityPersister(
318
322
// discriminatorFormula = null;
319
323
discriminatorFormulaTemplate = null ;
320
324
}
321
- discriminatorType = (BasicType <?>) persistentClass .getDiscriminator ().getType ();
322
- if ( persistentClass .isDiscriminatorValueNull () ) {
323
- discriminatorValue = NULL_DISCRIMINATOR ;
324
- discriminatorSQLValue = InFragment .NULL ;
325
- discriminatorInsertable = false ;
326
- }
327
- else if ( persistentClass .isDiscriminatorValueNotNull () ) {
328
- discriminatorValue = NOT_NULL_DISCRIMINATOR ;
329
- discriminatorSQLValue = InFragment .NOT_NULL ;
330
- discriminatorInsertable = false ;
331
- }
332
- else {
333
- discriminatorInsertable = persistentClass .isDiscriminatorInsertable () && !discrimValue .hasFormula ();
334
- try {
335
- discriminatorValue = discriminatorType .getJavaTypeDescriptor ()
336
- .fromString ( persistentClass .getDiscriminatorValue () );
337
- JdbcLiteralFormatter literalFormatter = discriminatorType .getJdbcType ()
338
- .getJdbcLiteralFormatter ( discriminatorType .getJavaTypeDescriptor () );
339
- discriminatorSQLValue = literalFormatter .toJdbcLiteral (
340
- discriminatorValue ,
341
- dialect ,
342
- factory .getWrapperOptions ()
343
- );
344
- }
345
- catch (ClassCastException cce ) {
346
- throw new MappingException ( "Illegal discriminator type: " + discriminatorType .getName () );
347
- }
348
- catch (Exception e ) {
349
- throw new MappingException ( "Could not format discriminator value to SQL string" , e );
350
- }
351
- }
325
+ discriminatorType = getDiscriminatorType ( persistentClass );
326
+ discriminatorValue = getDiscriminatorValue ( persistentClass );
327
+ discriminatorSQLValue = getDiscriminatorSQLValue ( persistentClass , dialect , factory );
328
+ discriminatorInsertable = isDiscriminatorInsertable ( persistentClass );
352
329
}
353
330
else {
354
331
forceDiscriminator = false ;
@@ -407,6 +384,8 @@ else if ( persistentClass.isDiscriminatorValueNotNull() ) {
407
384
// subclassFormulaTableNumberClosure = ArrayHelper.toIntArray( formulaJoinedNumbers );
408
385
subclassPropertyTableNumberClosure = ArrayHelper .toIntArray ( propertyJoinNumbers );
409
386
387
+ final List <Object > values = new ArrayList <>();
388
+ final List <String > sqlValues = new ArrayList <>();
410
389
int subclassSpan = persistentClass .getSubclassSpan () + 1 ;
411
390
subclassClosure = new String [subclassSpan ];
412
391
subclassClosure [0 ] = getEntityName ();
@@ -416,53 +395,106 @@ else if ( persistentClass.isDiscriminatorValueNotNull() ) {
416
395
discriminatorValue ,
417
396
getEntityName ()
418
397
);
419
- }
420
398
421
- // SUBCLASSES
422
- if ( persistentClass .isPolymorphic () ) {
399
+ if ( !getEntityMetamodel ().isAbstract () ) {
400
+ values .add ( discriminatorValue );
401
+ sqlValues .add ( discriminatorSQLValue );
402
+ }
403
+
404
+ // SUBCLASSES
423
405
int k = 1 ;
424
406
for ( Subclass subclass : persistentClass .getSubclasses () ) {
425
407
subclassClosure [k ++] = subclass .getEntityName ();
426
- if ( subclass .isDiscriminatorValueNull () ) {
427
- addSubclassByDiscriminatorValue (
428
- subclassesByDiscriminatorValueLocal ,
429
- NULL_DISCRIMINATOR ,
430
- subclass .getEntityName ()
431
- );
432
- }
433
- else if ( subclass .isDiscriminatorValueNotNull () ) {
434
- addSubclassByDiscriminatorValue (
435
- subclassesByDiscriminatorValueLocal ,
436
- NOT_NULL_DISCRIMINATOR ,
437
- subclass .getEntityName ()
438
- );
439
- }
440
- else {
441
- try {
442
- addSubclassByDiscriminatorValue (
443
- subclassesByDiscriminatorValueLocal ,
444
- discriminatorType .getJavaTypeDescriptor ()
445
- .fromString ( subclass .getDiscriminatorValue () ),
446
- subclass .getEntityName ()
447
- );
448
- }
449
- catch (ClassCastException cce ) {
450
- throw new MappingException ( "Illegal discriminator type: " + discriminatorType .getName () );
451
- }
452
- catch (Exception e ) {
453
- throw new MappingException ( "Error parsing discriminator value" , e );
454
- }
408
+ Object subclassDiscriminatorValue = getDiscriminatorValue ( subclass );
409
+ addSubclassByDiscriminatorValue (
410
+ subclassesByDiscriminatorValueLocal ,
411
+ subclassDiscriminatorValue ,
412
+ subclass .getEntityName ()
413
+ );
414
+
415
+ //copy/paste from EntityMetamodel:
416
+ boolean subclassAbstract = subclass .isAbstract () == null
417
+ ? subclass .hasPojoRepresentation () && ReflectHelper .isAbstractClass ( subclass .getMappedClass () )
418
+ : subclass .isAbstract ();
419
+
420
+ if ( !subclassAbstract ) {
421
+ values .add (subclassDiscriminatorValue );
422
+ sqlValues .add ( getDiscriminatorSQLValue ( subclass , dialect , factory ) );
455
423
}
456
424
}
457
425
}
458
426
459
427
// Don't hold a reference to an empty HashMap:
460
428
subclassesByDiscriminatorValue = CollectionHelper .toSmallMap ( subclassesByDiscriminatorValueLocal );
429
+ fullDiscriminatorSQLValues = ArrayHelper .toStringArray ( sqlValues );
430
+ fullDiscriminatorValues = ArrayHelper .toObjectArray ( values );
461
431
462
432
initSubclassPropertyAliasesMap ( persistentClass );
463
433
464
434
postConstruct ( creationContext .getMetadata () );
435
+ }
465
436
437
+ private static BasicType <?> getDiscriminatorType (PersistentClass persistentClass ) {
438
+ Type discriminatorType = persistentClass .getDiscriminator ().getType ();
439
+ if ( discriminatorType instanceof BasicType ) {
440
+ return (BasicType <?>) discriminatorType ;
441
+ }
442
+ else {
443
+ throw new MappingException ( "Illegal discriminator type: " + discriminatorType .getName () );
444
+ }
445
+ }
446
+
447
+ private static String getDiscriminatorSQLValue (
448
+ PersistentClass persistentClass ,
449
+ Dialect dialect ,
450
+ SessionFactoryImplementor factory ) {
451
+ if ( persistentClass .isDiscriminatorValueNull () ) {
452
+ return InFragment .NULL ;
453
+ }
454
+ else if ( persistentClass .isDiscriminatorValueNotNull () ) {
455
+ return InFragment .NOT_NULL ;
456
+ }
457
+ else {
458
+ BasicType <?> discriminatorType = getDiscriminatorType ( persistentClass );
459
+ Object discriminatorValue = getDiscriminatorValue ( persistentClass );
460
+ try {
461
+ JdbcLiteralFormatter literalFormatter = discriminatorType .getJdbcType ()
462
+ .getJdbcLiteralFormatter ( discriminatorType .getJavaTypeDescriptor () );
463
+ return literalFormatter .toJdbcLiteral (
464
+ discriminatorValue ,
465
+ dialect ,
466
+ factory .getWrapperOptions ()
467
+ );
468
+ }
469
+ catch (Exception e ) {
470
+ throw new MappingException ( "Could not format discriminator value to SQL string" , e );
471
+ }
472
+ }
473
+ }
474
+
475
+ private static Object getDiscriminatorValue (PersistentClass persistentClass ) {
476
+ if ( persistentClass .isDiscriminatorValueNull () ) {
477
+ return NULL_DISCRIMINATOR ;
478
+ }
479
+ else if ( persistentClass .isDiscriminatorValueNotNull () ) {
480
+ return NOT_NULL_DISCRIMINATOR ;
481
+ }
482
+ else {
483
+ BasicType <?> discriminatorType = getDiscriminatorType ( persistentClass );
484
+ try {
485
+ return discriminatorType .getJavaTypeDescriptor ().fromString ( persistentClass .getDiscriminatorValue () );
486
+ }
487
+ catch (Exception e ) {
488
+ throw new MappingException ( "Could not parse discriminator value" , e );
489
+ }
490
+ }
491
+ }
492
+
493
+ private static boolean isDiscriminatorInsertable (PersistentClass persistentClass ) {
494
+ return !persistentClass .isDiscriminatorValueNull ()
495
+ && !persistentClass .isDiscriminatorValueNotNull ()
496
+ && persistentClass .isDiscriminatorInsertable ()
497
+ && !persistentClass .getDiscriminator ().hasFormula ();
466
498
}
467
499
468
500
private static void addSubclassByDiscriminatorValue (Map <Object , String > subclassesByDiscriminatorValue , Object discriminatorValue , String entityName ) {
@@ -632,12 +664,7 @@ private String discriminatorFilterFragment(String alias, Set<String> treatAsDecl
632
664
frag .setColumn ( alias , getDiscriminatorColumnName () );
633
665
}
634
666
635
- if ( hasTreatAs ) {
636
- frag .addValues ( decodeTreatAsRequests ( treatAsDeclarations ) );
637
- }
638
- else {
639
- frag .addValues ( fullDiscriminatorSQLValues () );
640
- }
667
+ frag .addValues ( hasTreatAs ? decodeTreatAsRequests ( treatAsDeclarations ) : fullDiscriminatorSQLValues );
641
668
642
669
return frag .toFragmentString ();
643
670
}
@@ -649,7 +676,6 @@ private boolean needsDiscriminator() {
649
676
private String [] decodeTreatAsRequests (Set <String > treatAsDeclarations ) {
650
677
final List <String > values = new ArrayList <>();
651
678
for ( String subclass : treatAsDeclarations ) {
652
- //TODO: move getDiscriminatorSQLValue() to Loadable to get rid of Queryable
653
679
final Queryable queryable = (Queryable ) getFactory ()
654
680
.getRuntimeMetamodels ()
655
681
.getMappingMetamodel ()
@@ -679,48 +705,6 @@ private String[] decodeTreatAsRequests(Set<String> treatAsDeclarations) {
679
705
return ArrayHelper .toStringArray ( values );
680
706
}
681
707
682
- private String [] fullDiscriminatorSQLValues ;
683
-
684
- private String [] fullDiscriminatorSQLValues () {
685
- String [] fullDiscriminatorSQLValues = this .fullDiscriminatorSQLValues ;
686
- if ( fullDiscriminatorSQLValues == null ) {
687
- // first access; build it
688
- final List <String > values = new ArrayList <>();
689
- for ( String subclass : getSubclassClosure () ) {
690
- final Queryable queryable = (Queryable ) getFactory ().getRuntimeMetamodels ()
691
- .getMappingMetamodel ()
692
- .getEntityDescriptor ( subclass );
693
- if ( !queryable .isAbstract () ) {
694
- values .add ( queryable .getDiscriminatorSQLValue () );
695
- }
696
- }
697
- this .fullDiscriminatorSQLValues = fullDiscriminatorSQLValues = ArrayHelper .toStringArray ( values );
698
- }
699
-
700
- return fullDiscriminatorSQLValues ;
701
- }
702
-
703
- private Object [] fullDiscriminatorValues ;
704
-
705
- private Object [] fullDiscriminatorValues () {
706
- Object [] fullDiscriminatorValues = this .fullDiscriminatorValues ;
707
- if ( fullDiscriminatorValues == null ) {
708
- // first access; build it
709
- final List <Object > values = new ArrayList <>();
710
- for ( String subclass : getSubclassClosure () ) {
711
- final Loadable queryable = (Loadable ) getFactory ().getRuntimeMetamodels ()
712
- .getMappingMetamodel ()
713
- .getEntityDescriptor ( subclass );
714
- if ( !queryable .isAbstract () ) {
715
- values .add ( queryable .getDiscriminatorValue () );
716
- }
717
- }
718
- this .fullDiscriminatorValues = fullDiscriminatorValues = values .toArray (new Object [0 ]);
719
- }
720
-
721
- return fullDiscriminatorValues ;
722
- }
723
-
724
708
@ Override
725
709
public String getSubclassPropertyTableName (int i ) {
726
710
return subclassTableNameClosure [subclassPropertyTableNumberClosure [i ]];
@@ -903,10 +887,9 @@ private Predicate createDiscriminatorPredicate(
903
887
);
904
888
905
889
if ( hasSubclasses () ) {
906
- final Object [] discriminatorValues = fullDiscriminatorValues ();
907
- final List <Expression > values = new ArrayList <>( discriminatorValues .length );
890
+ final List <Expression > values = new ArrayList <>( fullDiscriminatorValues .length );
908
891
boolean hasNull = false , hasNonNull = false ;
909
- for ( Object discriminatorValue : discriminatorValues ) {
892
+ for ( Object discriminatorValue : fullDiscriminatorValues ) {
910
893
if ( discriminatorValue == NULL_DISCRIMINATOR ) {
911
894
hasNull = true ;
912
895
}
0 commit comments