@@ -94,6 +94,10 @@ public JpaModelBuildItem discoverModelAndRegisterForReflection() throws BuildExc
9494 enlistPotentialCdiBeanClasses (collector , annotation );
9595 }
9696
97+ enlistPotentialClassReferences (collector , ClassNames .GENERIC_GENERATOR , "type" , "strategy" );
98+ enlistPotentialClassReferences (collector , ClassNames .ID_GENERATOR_TYPE , "value" );
99+ enlistPotentialClassReferences (collector , ClassNames .VALUE_GENERATION_TYPE , "generatedBy" );
100+
97101 for (JpaModelPersistenceUnitContributionBuildItem persistenceUnitContribution : persistenceUnitContributions ) {
98102 enlistExplicitMappings (collector , persistenceUnitContribution );
99103 }
@@ -214,10 +218,16 @@ private void enlistOrmXmlMappingManagedClass(Collector collector, String package
214218 String nodeName ) {
215219 String name = safeGetClassName (packagePrefix , managed , nodeName );
216220 enlistExplicitClass (collector , name );
217- if (managed instanceof JaxbEntity ) {
221+ if (managed instanceof JaxbEntity entity ) {
218222 // The call to 'enlistExplicitClass' above may not
219223 // detect that this class is an entity if it is not annotated
220224 collector .entityTypes .add (name );
225+
226+ // Generators may be instantiated reflectively
227+ if (entity .getGenericGenerator () != null ) {
228+ var generator = entity .getGenericGenerator ();
229+ enlistPotentialClassReference (collector , generator == null ? null : generator .getClazz ());
230+ }
221231 }
222232
223233 enlistOrmXmlMappingListeners (collector , packagePrefix , managed .getEntityListenerContainer ());
@@ -437,6 +447,47 @@ private void enlistPotentialCdiBeanClasses(Collector collector, DotName dotName)
437447 }
438448 }
439449
450+ private void enlistPotentialClassReferences (Collector collector , DotName dotName , String ... referenceAttributes ) {
451+ Collection <AnnotationInstance > jpaAnnotations = index .getAnnotations (dotName );
452+
453+ if (jpaAnnotations == null ) {
454+ return ;
455+ }
456+
457+ for (AnnotationInstance annotation : jpaAnnotations ) {
458+ for (String referenceAttribute : referenceAttributes ) {
459+ var referenceValue = annotation .value (referenceAttribute );
460+ if (referenceValue == null ) {
461+ continue ;
462+ }
463+ String reference = switch (referenceValue .kind ()) {
464+ case CLASS -> referenceValue .asClass ().name ().toString ();
465+ case STRING -> {
466+ String stringRef = referenceValue .asString ();
467+ if (stringRef .isEmpty () || index .getClassByName (stringRef ) == null ) {
468+ // No reference, or reference to a built-in strategy name like 'sequence'
469+ // (which we can't resolve here and handle through GraalVMFeatures.registerGeneratorAndOptimizerClassesForReflections)
470+ yield null ;
471+ }
472+ yield stringRef ;
473+ }
474+ default -> null ;
475+ };
476+ enlistPotentialClassReference (collector , reference );
477+ }
478+ }
479+ }
480+
481+ /**
482+ * Add the class to the reflective list with only constructor and method access.
483+ */
484+ private void enlistPotentialClassReference (Collector collector , String reference ) {
485+ if (reference == null ) {
486+ return ;
487+ }
488+ collector .javaTypes .add (reference );
489+ }
490+
440491 /**
441492 * Add the class to the reflective list with full method and field access.
442493 * Add the superclasses recursively as well as the interfaces.
0 commit comments