27
27
import org .hibernate .boot .registry .classloading .spi .ClassLoaderService ;
28
28
import org .hibernate .boot .spi .InFlightMetadataCollector ;
29
29
import org .hibernate .boot .spi .MetadataBuildingContext ;
30
- import org .hibernate .boot .spi .PropertyData ;
31
30
import org .hibernate .cfg .AvailableSettings ;
32
31
import org .hibernate .dialect .Dialect ;
33
32
import org .hibernate .engine .config .spi .ConfigurationService ;
77
76
import jakarta .persistence .TableGenerator ;
78
77
import jakarta .persistence .Version ;
79
78
79
+ import static java .util .Collections .emptyMap ;
80
80
import static org .hibernate .boot .model .internal .AnnotationHelper .extractParameterMap ;
81
81
import static org .hibernate .boot .model .internal .BinderHelper .isCompositeId ;
82
82
import static org .hibernate .boot .model .internal .BinderHelper .isGlobalGeneratorNameGlobal ;
83
83
import static org .hibernate .internal .util .ReflectHelper .getDefaultConstructor ;
84
- import static org .hibernate .internal .util .StringHelper .isNotEmpty ;
85
84
import static org .hibernate .mapping .SimpleValue .DEFAULT_ID_GEN_STRATEGY ;
86
85
87
86
public class GeneratorBinder {
88
87
89
88
private static final Logger LOG = CoreLogging .logger ( BinderHelper .class );
90
89
91
90
public static Generator createLegacyIdentifierGenerator (
91
+ String strategy ,
92
92
SimpleValue simpleValue ,
93
93
Dialect dialect ,
94
- String defaultCatalog ,
95
- String defaultSchema ,
96
- RootClass rootClass ) {
97
- final Class <? extends Generator > generatorClass = generatorClass ( simpleValue );
94
+ RootClass rootClass ,
95
+ Map <String , Object > configuration ) {
96
+ final Class <? extends Generator > generatorClass = generatorClass ( strategy , simpleValue );
98
97
final Constructor <? extends Generator > defaultConstructor = getDefaultConstructor ( generatorClass );
99
98
if ( defaultConstructor == null ) {
100
99
throw new org .hibernate .InstantiationException ( "No default constructor for id generator class" , generatorClass );
@@ -107,15 +106,14 @@ public static Generator createLegacyIdentifierGenerator(
107
106
throw new org .hibernate .InstantiationException ( "Could not instantiate id generator" , generatorClass , e );
108
107
}
109
108
if ( identifierGenerator instanceof Configurable ) {
110
- final Properties parameters = collectParameters ( simpleValue , dialect , defaultCatalog , defaultSchema , rootClass );
109
+ final Properties parameters = collectParameters ( simpleValue , dialect , rootClass , configuration );
111
110
final Configurable configurable = (Configurable ) identifierGenerator ;
112
111
configurable .configure ( simpleValue .getType (), parameters , simpleValue .getServiceRegistry () );
113
112
}
114
113
return identifierGenerator ;
115
114
}
116
115
117
- private static Class <? extends Generator > generatorClass (SimpleValue simpleValue ) {
118
- String strategy = simpleValue .getIdentifierGeneratorStrategy ();
116
+ private static Class <? extends Generator > generatorClass (String strategy , SimpleValue simpleValue ) {
119
117
if ( "native" .equals (strategy ) ) {
120
118
strategy =
121
119
simpleValue .getMetadata ().getDatabase ().getDialect ()
@@ -160,26 +158,14 @@ private static Class<? extends Generator> generatorClass(SimpleValue simpleValue
160
158
public static Properties collectParameters (
161
159
SimpleValue simpleValue ,
162
160
Dialect dialect ,
163
- String defaultCatalog ,
164
- String defaultSchema ,
165
- RootClass rootClass ) {
161
+ RootClass rootClass ,
162
+ Map <String , Object > configuration ) {
166
163
final ConfigurationService configService =
167
164
simpleValue .getMetadata ().getMetadataBuildingOptions ().getServiceRegistry ()
168
165
.requireService ( ConfigurationService .class );
169
166
170
167
final Properties params = new Properties ();
171
168
172
- // This is for backwards compatibility only;
173
- // when this method is called by Hibernate ORM, defaultSchema and defaultCatalog are always
174
- // null, and defaults are handled later.
175
- if ( defaultSchema != null ) {
176
- params .setProperty ( PersistentIdentifierGenerator .SCHEMA , defaultSchema );
177
- }
178
-
179
- if ( defaultCatalog != null ) {
180
- params .setProperty ( PersistentIdentifierGenerator .CATALOG , defaultCatalog );
181
- }
182
-
183
169
// default initial value and allocation size per-JPA defaults
184
170
params .setProperty ( OptimizableGenerator .INITIAL_PARAM ,
185
171
String .valueOf ( OptimizableGenerator .DEFAULT_INITIAL_VALUE ) );
@@ -216,12 +202,6 @@ public static Properties collectParameters(
216
202
params .setProperty ( OptimizableGenerator .IMPLICIT_NAME_BASE , tableName );
217
203
}
218
204
219
- if ( simpleValue .getIdentifierGeneratorParameters () != null ) {
220
- params .putAll ( simpleValue .getIdentifierGeneratorParameters () );
221
- }
222
-
223
- // TODO : we should pass along all settings once "config lifecycle" is hashed out...
224
-
225
205
params .put ( IdentifierGenerator .CONTRIBUTOR_NAME ,
226
206
simpleValue .getBuildingContext ().getCurrentContributorName () );
227
207
@@ -231,14 +211,16 @@ public static Properties collectParameters(
231
211
settings .get ( AvailableSettings .PREFERRED_POOLED_OPTIMIZER ) );
232
212
}
233
213
214
+ params .putAll ( configuration );
215
+
234
216
return params ;
235
217
}
236
218
237
219
private static String identityTablesString (Dialect dialect , RootClass rootClass ) {
238
220
final StringBuilder tables = new StringBuilder ();
239
221
for ( Table table : rootClass .getIdentityTables () ) {
240
222
tables .append ( table .getQuotedName ( dialect ) );
241
- if ( tables .length ()> 0 ) {
223
+ if ( ! tables .isEmpty () ) {
242
224
tables .append ( ", " );
243
225
}
244
226
}
@@ -286,6 +268,7 @@ public static void makeIdGenerator(
286
268
parameters .put ( PersistentIdentifierGenerator .IDENTIFIER_NORMALIZER , buildingContext .getObjectNameNormalizer () );
287
269
parameters .put ( IdentifierGenerator .GENERATOR_NAME , generatorName );
288
270
271
+ final String generatorStrategy ;
289
272
if ( !generatorName .isEmpty () ) {
290
273
//we have a named generator
291
274
final IdentifierGeneratorDefinition definition =
@@ -296,22 +279,24 @@ public static void makeIdGenerator(
296
279
+ " (define a named generator using '@SequenceGenerator', '@TableGenerator', or '@GenericGenerator')" );
297
280
}
298
281
//This is quite vague in the spec but a generator could override the generator choice
299
- final String identifierGeneratorStrategy = definition .getStrategy ();
300
282
//yuk! this is a hack not to override 'AUTO' even if generator is set
301
283
final boolean avoidOverriding =
302
- identifierGeneratorStrategy .equals ( "identity" )
303
- || identifierGeneratorStrategy .equals ( "seqhilo" );
284
+ definition . getStrategy () .equals ( "identity" )
285
+ || definition . getStrategy () .equals ( "seqhilo" );
304
286
if ( generatorType == null || !avoidOverriding ) {
305
- generatorType = identifierGeneratorStrategy ;
287
+ generatorStrategy = definition .getStrategy ();
288
+ }
289
+ else {
290
+ generatorStrategy = generatorType ;
306
291
}
307
292
//checkIfMatchingGenerator(definition, generatorType, generatorName);
308
293
parameters .putAll ( definition .getParameters () );
309
294
}
310
- id .setIdentifierGeneratorStrategy ( generatorType );
311
- id .setIdentifierGeneratorParameters ( parameters );
312
- if ( DEFAULT_ID_GEN_STRATEGY .equals ( generatorType ) ) {
313
- id .setNullValue ( "undefined" );
295
+ else {
296
+ generatorStrategy = generatorType ;
314
297
}
298
+
299
+ setGeneratorCreator ( id , parameters , generatorStrategy );
315
300
}
316
301
317
302
/**
@@ -701,9 +686,8 @@ private static void callConfigure(GeneratorCreationContext creationContext, Gene
701
686
Properties parameters = collectParameters (
702
687
(SimpleValue ) value ,
703
688
creationContext .getDatabase ().getDialect (),
704
- creationContext .getDefaultCatalog (),
705
- creationContext .getDefaultSchema (),
706
- creationContext .getPersistentClass ().getRootClass ()
689
+ creationContext .getPersistentClass ().getRootClass (),
690
+ emptyMap ()
707
691
);
708
692
( (Configurable ) generator ).configure ( value .getType (), parameters , creationContext .getServiceRegistry () );
709
693
}
@@ -749,51 +733,67 @@ static void createIdGenerator(
749
733
}
750
734
}
751
735
752
- static IdentifierGeneratorDefinition createForeignGenerator (PropertyData mapsIdProperty ) {
753
- final IdentifierGeneratorDefinition .Builder foreignGeneratorBuilder =
754
- new IdentifierGeneratorDefinition .Builder ();
755
- foreignGeneratorBuilder .setName ( "Hibernate-local--foreign generator" );
756
- foreignGeneratorBuilder .setStrategy ( "foreign" );
757
- foreignGeneratorBuilder .addParam ( "property" , mapsIdProperty .getPropertyName () );
758
- return foreignGeneratorBuilder .build ();
759
- }
760
-
761
- public static void makeIdentifier (
736
+ /**
737
+ * Set up the identifier generator for an id defined in a {@code hbm.xml} mapping.
738
+ *
739
+ * @see org.hibernate.boot.model.source.internal.hbm.ModelBinder
740
+ */
741
+ public static void makeIdGenerator (
762
742
final MappingDocument sourceDocument ,
763
- IdentifierGeneratorDefinition generator ,
764
- String unsavedValue ,
743
+ IdentifierGeneratorDefinition definition ,
765
744
SimpleValue identifierValue ,
766
745
MetadataBuildingContext buildingContext ) {
767
- if ( generator != null ) {
746
+
747
+ if ( definition != null ) {
768
748
final Map <String ,Object > params = new HashMap <>();
769
749
770
750
// see if the specified generator name matches a registered <identifier-generator/>
771
- String generatorName = generator .getStrategy ();
772
751
final IdentifierGeneratorDefinition generatorDef =
773
- sourceDocument .getMetadataCollector ().getIdentifierGenerator ( generatorName );
752
+ sourceDocument .getMetadataCollector ().getIdentifierGenerator ( definition .getName () );
753
+ final String generatorStrategy ;
774
754
if ( generatorDef != null ) {
775
- generatorName = generatorDef .getStrategy ();
755
+ generatorStrategy = generatorDef .getStrategy ();
776
756
params .putAll ( generatorDef .getParameters () );
777
757
}
758
+ else {
759
+ generatorStrategy = definition .getStrategy ();
760
+ }
778
761
779
762
// YUCK! but cannot think of a clean way to do this given the string-config based scheme
780
763
params .put ( PersistentIdentifierGenerator .IDENTIFIER_NORMALIZER ,
781
764
buildingContext .getObjectNameNormalizer () );
782
765
783
- params .putAll ( generator .getParameters () );
766
+ params .putAll ( definition .getParameters () );
784
767
785
- identifierValue .setIdentifierGeneratorStrategy ( generatorName );
786
- identifierValue .setIdentifierGeneratorParameters ( params );
768
+ setGeneratorCreator ( identifierValue , params , generatorStrategy );
787
769
}
770
+ }
788
771
789
- if ( isNotEmpty ( unsavedValue ) ) {
790
- identifierValue .setNullValue ( unsavedValue );
791
- }
792
- else if ( DEFAULT_ID_GEN_STRATEGY .equals ( identifierValue .getIdentifierGeneratorStrategy () ) ) {
793
- identifierValue .setNullValue ( "undefined" );
794
- }
795
- else {
796
- identifierValue .setNullValue ( null );
797
- }
772
+ private static void setGeneratorCreator (
773
+ SimpleValue identifierValue ,
774
+ Map <String , Object > parameters ,
775
+ String generatorStrategy ) {
776
+ identifierValue .setCustomIdGeneratorCreator ( new IdentifierGeneratorCreator () {
777
+ @ Override
778
+ public Generator createGenerator (CustomIdGeneratorCreationContext context ) {
779
+ final Generator generator =
780
+ createLegacyIdentifierGenerator (
781
+ generatorStrategy ,
782
+ identifierValue ,
783
+ context .getDatabase ().getDialect (),
784
+ context .getRootClass (),
785
+ parameters
786
+ );
787
+ if ( generator instanceof IdentityGenerator ) {
788
+ identifierValue .setColumnToIdentity ();
789
+ }
790
+ return generator ;
791
+ }
792
+
793
+ @ Override
794
+ public boolean isAssigned () {
795
+ return DEFAULT_ID_GEN_STRATEGY .equals ( generatorStrategy );
796
+ }
797
+ } );
798
798
}
799
799
}
0 commit comments