29
29
import org .hibernate .SessionEventListener ;
30
30
import org .hibernate .SessionFactoryObserver ;
31
31
import org .hibernate .context .spi .TenantSchemaMapper ;
32
+ import org .hibernate .metamodel .mapping .EntityMappingType ;
33
+ import org .hibernate .metamodel .mapping .internal .MappingModelCreationProcess ;
32
34
import org .hibernate .type .TimeZoneStorageStrategy ;
33
35
import org .hibernate .annotations .CacheLayout ;
34
36
import org .hibernate .boot .SchemaAutoTooling ;
@@ -196,6 +198,8 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
196
198
private final HqlTranslator hqlTranslator ;
197
199
private final SqmMultiTableMutationStrategy sqmMultiTableMutationStrategy ;
198
200
private final SqmMultiTableInsertStrategy sqmMultiTableInsertStrategy ;
201
+ private final Constructor <SqmMultiTableMutationStrategy > sqmMultiTableMutationStrategyConstructor ;
202
+ private final Constructor <SqmMultiTableInsertStrategy > sqmMultiTableInsertStrategyConstructor ;
199
203
private final SqmTranslatorFactory sqmTranslatorFactory ;
200
204
private final Boolean useOfJdbcNamedParametersEnabled ;
201
205
private boolean namedQueryStartupCheckingEnabled ;
@@ -406,10 +410,14 @@ public SessionFactoryOptionsBuilder(StandardServiceRegistry serviceRegistry, Boo
406
410
extractPropertyValue ( AvailableSettings .QUERY_MULTI_TABLE_MUTATION_STRATEGY , settings );
407
411
sqmMultiTableMutationStrategy =
408
412
resolveSqmMutationStrategy ( sqmMutationStrategyImplName , serviceRegistry , strategySelector );
413
+ sqmMultiTableMutationStrategyConstructor =
414
+ resolveSqmMutationStrategyConstructor ( sqmMutationStrategyImplName , strategySelector );
409
415
final String sqmInsertStrategyImplName =
410
416
extractPropertyValue ( AvailableSettings .QUERY_MULTI_TABLE_INSERT_STRATEGY , settings );
411
417
sqmMultiTableInsertStrategy =
412
418
resolveSqmInsertStrategy ( sqmInsertStrategyImplName , serviceRegistry , strategySelector );
419
+ sqmMultiTableInsertStrategyConstructor =
420
+ resolveSqmInsertStrategyConstructor ( sqmInsertStrategyImplName , strategySelector );
413
421
414
422
useOfJdbcNamedParametersEnabled =
415
423
configurationService .getSetting ( CALLABLE_NAMED_PARAMS_ENABLED , BOOLEAN , true );
@@ -622,6 +630,7 @@ private SqmMultiTableMutationStrategy resolveSqmMutationStrategy(
622
630
strategyClass -> {
623
631
Constructor <SqmMultiTableMutationStrategy > dialectConstructor = null ;
624
632
Constructor <SqmMultiTableMutationStrategy > emptyConstructor = null ;
633
+ Constructor <SqmMultiTableMutationStrategy > entityBasedConstructor = null ;
625
634
// todo (6.0) : formalize the allowed constructor parameterizations
626
635
for ( Constructor <?> declaredConstructor : strategyClass .getDeclaredConstructors () ) {
627
636
final Class <?>[] parameterTypes = declaredConstructor .getParameterTypes ();
@@ -632,29 +641,59 @@ private SqmMultiTableMutationStrategy resolveSqmMutationStrategy(
632
641
else if ( parameterTypes .length == 0 ) {
633
642
emptyConstructor = (Constructor <SqmMultiTableMutationStrategy >) declaredConstructor ;
634
643
}
644
+ else if ( parameterTypes .length == 2 && parameterTypes [0 ] == EntityMappingType .class && parameterTypes [1 ] == MappingModelCreationProcess .class ) {
645
+ entityBasedConstructor = (Constructor <SqmMultiTableMutationStrategy >) declaredConstructor ;
646
+ }
635
647
}
636
648
637
- try {
638
- if ( dialectConstructor != null ) {
639
- return dialectConstructor .newInstance (
640
- serviceRegistry .requireService ( JdbcServices .class ).getDialect ()
641
- );
649
+ if ( entityBasedConstructor == null ) {
650
+ try {
651
+ if ( dialectConstructor != null ) {
652
+ return dialectConstructor .newInstance (
653
+ serviceRegistry .requireService ( JdbcServices .class ).getDialect ()
654
+ );
655
+ }
656
+ else if ( emptyConstructor != null ) {
657
+ return emptyConstructor .newInstance ();
658
+ }
642
659
}
643
- else if ( emptyConstructor != null ) {
644
- return emptyConstructor .newInstance ();
660
+ catch (Exception e ) {
661
+ throw new StrategySelectionException (
662
+ String .format ( "Could not instantiate named strategy class [%s]" ,
663
+ strategyClass .getName () ),
664
+ e
665
+ );
645
666
}
667
+ throw new IllegalArgumentException (
668
+ "Cannot instantiate the class [" + strategyClass .getName () + "] because it does not have a constructor that accepts a dialect or an empty constructor" );
646
669
}
647
- catch (Exception e ) {
648
- throw new StrategySelectionException (
649
- String .format ( "Could not instantiate named strategy class [%s]" , strategyClass .getName () ),
650
- e
651
- );
670
+ else {
671
+ return null ;
652
672
}
653
- throw new IllegalArgumentException ( "Cannot instantiate the class [" + strategyClass .getName () + "] because it does not have a constructor that accepts a dialect or an empty constructor" );
654
673
}
655
674
);
656
675
}
657
676
677
+ @ SuppressWarnings ("unchecked" )
678
+ private Constructor <SqmMultiTableMutationStrategy > resolveSqmMutationStrategyConstructor (
679
+ String strategyName ,
680
+ StrategySelector strategySelector ) {
681
+ if ( strategyName == null ) {
682
+ return null ;
683
+ }
684
+
685
+ Class <? extends SqmMultiTableMutationStrategy > strategyClass =
686
+ strategySelector .selectStrategyImplementor ( SqmMultiTableMutationStrategy .class , strategyName );
687
+ for ( Constructor <?> declaredConstructor : strategyClass .getDeclaredConstructors () ) {
688
+ final Class <?>[] parameterTypes = declaredConstructor .getParameterTypes ();
689
+ if ( parameterTypes .length == 2 && parameterTypes [0 ] == EntityMappingType .class && parameterTypes [1 ] == MappingModelCreationProcess .class ) {
690
+ return (Constructor <SqmMultiTableMutationStrategy >) declaredConstructor ;
691
+ }
692
+ }
693
+
694
+ return null ;
695
+ }
696
+
658
697
@ SuppressWarnings ("unchecked" )
659
698
private SqmMultiTableInsertStrategy resolveSqmInsertStrategy (
660
699
String strategyName ,
@@ -704,6 +743,26 @@ else if ( emptyConstructor != null ) {
704
743
);
705
744
}
706
745
746
+ @ SuppressWarnings ("unchecked" )
747
+ private Constructor <SqmMultiTableInsertStrategy > resolveSqmInsertStrategyConstructor (
748
+ String strategyName ,
749
+ StrategySelector strategySelector ) {
750
+ if ( strategyName == null ) {
751
+ return null ;
752
+ }
753
+
754
+ Class <? extends SqmMultiTableInsertStrategy > strategyClass =
755
+ strategySelector .selectStrategyImplementor ( SqmMultiTableInsertStrategy .class , strategyName );
756
+ for ( Constructor <?> declaredConstructor : strategyClass .getDeclaredConstructors () ) {
757
+ final Class <?>[] parameterTypes = declaredConstructor .getParameterTypes ();
758
+ if ( parameterTypes .length == 2 && parameterTypes [0 ] == EntityMappingType .class && parameterTypes [1 ] == MappingModelCreationProcess .class ) {
759
+ return (Constructor <SqmMultiTableInsertStrategy >) declaredConstructor ;
760
+ }
761
+ }
762
+
763
+ return null ;
764
+ }
765
+
707
766
private HqlTranslator resolveHqlTranslator (
708
767
String producerName ,
709
768
StandardServiceRegistry serviceRegistry ,
@@ -924,6 +983,38 @@ public SqmMultiTableInsertStrategy getCustomSqmMultiTableInsertStrategy() {
924
983
return sqmMultiTableInsertStrategy ;
925
984
}
926
985
986
+ @ Override
987
+ public SqmMultiTableMutationStrategy resolveCustomSqmMultiTableMutationStrategy (EntityMappingType rootEntityDescriptor , MappingModelCreationProcess creationProcess ) {
988
+ if ( sqmMultiTableMutationStrategyConstructor != null ) {
989
+ try {
990
+ return sqmMultiTableMutationStrategyConstructor .newInstance ( rootEntityDescriptor , creationProcess );
991
+ }
992
+ catch (Exception e ) {
993
+ throw new StrategySelectionException (
994
+ String .format ( "Could not instantiate named strategy class [%s]" , sqmMultiTableMutationStrategyConstructor .getDeclaringClass ().getName () ),
995
+ e
996
+ );
997
+ }
998
+ }
999
+ return null ;
1000
+ }
1001
+
1002
+ @ Override
1003
+ public SqmMultiTableInsertStrategy resolveCustomSqmMultiTableInsertStrategy (EntityMappingType rootEntityDescriptor , MappingModelCreationProcess creationProcess ) {
1004
+ if ( sqmMultiTableInsertStrategyConstructor != null ) {
1005
+ try {
1006
+ return sqmMultiTableInsertStrategyConstructor .newInstance ( rootEntityDescriptor , creationProcess );
1007
+ }
1008
+ catch (Exception e ) {
1009
+ throw new StrategySelectionException (
1010
+ String .format ( "Could not instantiate named strategy class [%s]" , sqmMultiTableInsertStrategyConstructor .getDeclaringClass ().getName () ),
1011
+ e
1012
+ );
1013
+ }
1014
+ }
1015
+ return null ;
1016
+ }
1017
+
927
1018
@ Override
928
1019
public boolean isUseOfJdbcNamedParametersEnabled () {
929
1020
return useOfJdbcNamedParametersEnabled ;
0 commit comments