Skip to content

Commit 53f9321

Browse files
dreab8sebersole
authored andcommitted
HHH-18520 Fix issue with dynamic model
1 parent 92c434d commit 53f9321

File tree

5 files changed

+159
-26
lines changed

5 files changed

+159
-26
lines changed

hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyInferredData.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import org.hibernate.MappingException;
1010
import org.hibernate.annotations.Target;
11+
import org.hibernate.boot.models.internal.ModelsHelper;
1112
import org.hibernate.boot.spi.AccessType;
1213
import org.hibernate.boot.spi.MetadataBuildingContext;
1314
import org.hibernate.boot.spi.PropertyData;
@@ -87,8 +88,11 @@ public TypeDetails getPropertyType() throws MappingException {
8788
if ( targetAnnotation != null ) {
8889
final String targetName = targetAnnotation.value();
8990
final SourceModelBuildingContext sourceModelBuildingContext = sourceModelContext;
90-
final ClassDetails classDetails = sourceModelBuildingContext.getClassDetailsRegistry()
91-
.resolveClassDetails( targetName );
91+
final ClassDetails classDetails = ModelsHelper.resolveClassDetails(
92+
targetName,
93+
sourceModelBuildingContext.getClassDetailsRegistry(),
94+
() -> new DynamicClassDetails( targetName, sourceModelContext )
95+
);
9296
return new ClassTypeDetailsImpl( classDetails, TypeDetails.Kind.CLASS );
9397
}
9498

@@ -117,8 +121,11 @@ public TypeDetails getClassOrElementType() throws MappingException {
117121
final org.hibernate.boot.internal.Target annotationUsage = propertyMember.getDirectAnnotationUsage( org.hibernate.boot.internal.Target.class );
118122
if ( annotationUsage != null ) {
119123
final String targetName = annotationUsage.value();
120-
final ClassDetails classDetails = sourceModelBuildingContext.getClassDetailsRegistry()
121-
.resolveClassDetails( targetName );
124+
final ClassDetails classDetails = ModelsHelper.resolveClassDetails(
125+
targetName,
126+
sourceModelBuildingContext.getClassDetailsRegistry(),
127+
() -> new DynamicClassDetails( targetName, sourceModelBuildingContext )
128+
);
122129
return new ClassTypeDetailsImpl( classDetails, TypeDetails.Kind.CLASS );
123130
}
124131

@@ -169,4 +176,6 @@ public MemberDetails getAttributeMember() {
169176
public ClassDetails getDeclaringClass() {
170177
return declaringClass;
171178
}
179+
180+
172181
}

hibernate-core/src/main/java/org/hibernate/boot/models/internal/ModelsHelper.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@
66
*/
77
package org.hibernate.boot.models.internal;
88

9+
import java.util.function.Supplier;
10+
911
import org.hibernate.annotations.TenantId;
12+
import org.hibernate.models.internal.MutableClassDetailsRegistry;
1013
import org.hibernate.models.internal.jdk.JdkBuilders;
14+
import org.hibernate.models.jandex.internal.JandexClassDetails;
1115
import org.hibernate.models.jandex.spi.JandexModelBuildingContext;
1216
import org.hibernate.models.spi.AnnotationDescriptorRegistry;
17+
import org.hibernate.models.spi.ClassDetails;
1318
import org.hibernate.models.spi.ClassDetailsRegistry;
1419
import org.hibernate.models.spi.RegistryPrimer;
1520
import org.hibernate.models.spi.SourceModelBuildingContext;
@@ -51,8 +56,26 @@ public static void preFillRegistries(RegistryPrimer.Contributions contributions,
5156
);
5257
}
5358

54-
classDetailsRegistry.resolveClassDetails( className );
59+
resolveClassDetails(
60+
className,
61+
classDetailsRegistry,
62+
() -> new JandexClassDetails( knownClass, buildingContext )
63+
);
5564
}
5665
}
5766
}
67+
68+
public static ClassDetails resolveClassDetails(
69+
String className,
70+
ClassDetailsRegistry classDetailsRegistry,
71+
Supplier<ClassDetails> classDetailsSupplier) {
72+
ClassDetails classDetails = classDetailsRegistry.findClassDetails( className );
73+
if ( classDetails != null ) {
74+
return classDetails;
75+
}
76+
classDetails = classDetailsSupplier.get();
77+
classDetailsRegistry.as( MutableClassDetailsRegistry.class )
78+
.addClassDetails( className, classDetails );
79+
return classDetails;
80+
}
5881
}

hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/ManagedTypeProcessor.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.hibernate.boot.models.annotations.internal.CacheAnnotation;
3333
import org.hibernate.boot.models.annotations.internal.CacheableJpaAnnotation;
3434
import org.hibernate.boot.models.annotations.internal.ExtendsXmlAnnotation;
35+
import org.hibernate.boot.models.internal.ModelsHelper;
3536
import org.hibernate.boot.models.xml.internal.attr.BasicAttributeProcessing;
3637
import org.hibernate.boot.models.xml.internal.attr.BasicIdAttributeProcessing;
3738
import org.hibernate.boot.models.xml.internal.attr.CommonAttributeProcessing;
@@ -100,7 +101,19 @@ public static void processCompleteEntity(
100101

101102
memberAdjuster = ManagedTypeProcessor::adjustDynamicTypeMember;
102103
classAccessType = AccessType.FIELD;
103-
classDetails = (MutableClassDetails) classDetailsRegistry.resolveClassDetails( jaxbEntity.getName() );
104+
classDetails = (MutableClassDetails) ModelsHelper.resolveClassDetails(
105+
jaxbEntity.getName(),
106+
classDetailsRegistry,
107+
() ->
108+
new DynamicClassDetails(
109+
jaxbEntity.getName(),
110+
null,
111+
false,
112+
null,
113+
null,
114+
xmlDocumentContext.getModelBuildingContext()
115+
)
116+
);
104117

105118
prepareDynamicClass( classDetails, jaxbEntity, xmlDocumentContext );
106119
}
@@ -934,8 +947,15 @@ public static void processCompleteEmbeddable(
934947
throw new ModelsException( "Embeddable did not define class nor name" );
935948
}
936949
// no class == dynamic...
937-
classDetails = (MutableClassDetails) classDetailsRegistry
938-
.resolveClassDetails( jaxbEmbeddable.getName() );
950+
classDetails = (MutableClassDetails) ModelsHelper.resolveClassDetails(
951+
jaxbEmbeddable.getName(),
952+
classDetailsRegistry,
953+
() ->
954+
new DynamicClassDetails(
955+
jaxbEmbeddable.getName(),
956+
xmlDocumentContext.getModelBuildingContext()
957+
)
958+
);
939959
classAccessType = AccessType.FIELD;
940960
memberAdjuster = ManagedTypeProcessor::adjustDynamicTypeMember;
941961

hibernate-core/src/main/java/org/hibernate/boot/models/xml/spi/XmlDocumentContext.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute;
2121
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute;
2222
import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeImpl;
23+
import org.hibernate.boot.models.internal.ModelsHelper;
2324
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
2425
import org.hibernate.boot.spi.BootstrapContext;
2526
import org.hibernate.boot.spi.EffectiveMappingDefaults;
@@ -137,17 +138,30 @@ else if ( jdbcTypeCode != null ) {
137138
// <embedded/>, <embedded-id/>
138139
final String target = jaxbEmbeddedMapping.getTarget();
139140
if ( isNotEmpty( target ) ) {
140-
return (MutableClassDetails) getModelBuildingContext().getClassDetailsRegistry()
141-
.resolveClassDetails( target );
141+
return (MutableClassDetails) ModelsHelper.resolveClassDetails(
142+
target,
143+
getModelBuildingContext().getClassDetailsRegistry(),
144+
() -> new DynamicClassDetails( target, getModelBuildingContext() )
145+
);
142146
}
143147
// fall through to exception
144148
}
145149

146150
if ( jaxbPersistentAttribute instanceof JaxbAssociationAttribute jaxbAssociationAttribute ) {
147151
final String target = jaxbAssociationAttribute.getTargetEntity();
148152
if ( isNotEmpty( target ) ) {
149-
return (MutableClassDetails) getModelBuildingContext().getClassDetailsRegistry()
150-
.resolveClassDetails( target );
153+
return (MutableClassDetails) ModelsHelper.resolveClassDetails(
154+
target,
155+
getModelBuildingContext().getClassDetailsRegistry(),
156+
() -> new DynamicClassDetails(
157+
target,
158+
null,
159+
false,
160+
null,
161+
null,
162+
getModelBuildingContext()
163+
)
164+
);
151165
}
152166
// fall through to exception
153167
}

hibernate-core/src/test/java/org/hibernate/orm/test/intg/AdditionalMappingContributorTests.java

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,22 @@
1111
import java.util.List;
1212

1313
import org.hibernate.boot.ResourceStreamLocator;
14+
import org.hibernate.boot.models.HibernateAnnotations;
15+
import org.hibernate.boot.models.JpaAnnotations;
16+
import org.hibernate.boot.models.annotations.internal.EntityJpaAnnotation;
17+
import org.hibernate.boot.models.internal.ModelsHelper;
1418
import org.hibernate.boot.spi.AdditionalMappingContributions;
1519
import org.hibernate.boot.spi.AdditionalMappingContributor;
1620
import org.hibernate.boot.spi.InFlightMetadataCollector;
1721
import org.hibernate.boot.spi.MetadataBuildingContext;
1822
import org.hibernate.mapping.PersistentClass;
23+
import org.hibernate.models.internal.dynamic.DynamicClassDetails;
24+
import org.hibernate.models.internal.dynamic.DynamicFieldDetails;
25+
import org.hibernate.models.internal.jdk.JdkClassDetails;
1926
import org.hibernate.models.spi.ClassDetails;
2027
import org.hibernate.models.spi.ClassDetailsRegistry;
28+
import org.hibernate.models.spi.MutableMemberDetails;
29+
import org.hibernate.models.spi.SourceModelBuildingContext;
2130

2231
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
2332
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry.JavaService;
@@ -292,28 +301,53 @@ public void contribute(
292301
InFlightMetadataCollector metadata,
293302
ResourceStreamLocator resourceStreamLocator,
294303
MetadataBuildingContext buildingContext) {
295-
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getMetadataCollector()
296-
.getSourceModelBuildingContext()
304+
SourceModelBuildingContext sourceModelBuildingContext = buildingContext.getMetadataCollector()
305+
.getSourceModelBuildingContext();
306+
final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext
297307
.getClassDetailsRegistry();
298308

299-
contributeEntity4Details( contributions, classDetailsRegistry );
300-
contributeEntity5Details( contributions, classDetailsRegistry );
309+
contributeEntity4Details( contributions, sourceModelBuildingContext, classDetailsRegistry );
310+
contributeEntity5Details( contributions, sourceModelBuildingContext, classDetailsRegistry );
301311
}
302312

303313
private static void contributeEntity4Details(
304314
AdditionalMappingContributions contributions,
315+
SourceModelBuildingContext sourceModelBuildingContext,
305316
ClassDetailsRegistry classDetailsRegistry) {
306-
final ClassDetails entity4Details = classDetailsRegistry.resolveClassDetails(
307-
Entity4.class.getName()
317+
final ClassDetails entity4Details = ModelsHelper.resolveClassDetails(
318+
Entity4.class.getName(),
319+
classDetailsRegistry,
320+
() ->
321+
new JdkClassDetails( Entity4.class, sourceModelBuildingContext )
308322
);
309323
contributions.contributeManagedClass( entity4Details );
310324
}
311325

312326
private static void contributeEntity5Details(
313327
AdditionalMappingContributions contributions,
328+
SourceModelBuildingContext modelBuildingContext,
314329
ClassDetailsRegistry classDetailsRegistry) {
315-
final ClassDetails entity5Details = classDetailsRegistry.resolveClassDetails(
316-
Entity5.class.getName()
330+
final ClassDetails entity5Details = ModelsHelper.resolveClassDetails(
331+
Entity5.class.getName(),
332+
classDetailsRegistry,
333+
() -> {
334+
final JdkClassDetails jdkClassDetails = new JdkClassDetails(
335+
Entity5.class,
336+
modelBuildingContext
337+
);
338+
339+
final EntityJpaAnnotation entityUsage = (EntityJpaAnnotation) jdkClassDetails.applyAnnotationUsage(
340+
JpaAnnotations.ENTITY,
341+
modelBuildingContext
342+
);
343+
entityUsage.name( "___Entity5___" );
344+
345+
final MutableMemberDetails idField = (MutableMemberDetails) jdkClassDetails.findFieldByName(
346+
"id" );
347+
idField.applyAnnotationUsage( JpaAnnotations.ID, modelBuildingContext );
348+
349+
return jdkClassDetails;
350+
}
317351
);
318352
contributions.contributeManagedClass( entity5Details );
319353
}
@@ -326,17 +360,50 @@ public void contribute(
326360
InFlightMetadataCollector metadata,
327361
ResourceStreamLocator resourceStreamLocator,
328362
MetadataBuildingContext buildingContext) {
329-
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getMetadataCollector()
330-
.getSourceModelBuildingContext()
331-
.getClassDetailsRegistry();
332-
contributeEntity6Details( contributions, classDetailsRegistry );
363+
final SourceModelBuildingContext sourceModelBuildingContext = buildingContext.getMetadataCollector()
364+
.getSourceModelBuildingContext();
365+
final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry();
366+
contributeEntity6Details( contributions, sourceModelBuildingContext, classDetailsRegistry );
333367
}
334368

335369
private void contributeEntity6Details(
336370
AdditionalMappingContributions contributions,
371+
SourceModelBuildingContext modelBuildingContext,
337372
ClassDetailsRegistry classDetailsRegistry) {
338-
final ClassDetails entity6Details = classDetailsRegistry.resolveClassDetails(
339-
"Entity6"
373+
final ClassDetails entity6Details = ModelsHelper.resolveClassDetails(
374+
"Entity6",
375+
classDetailsRegistry,
376+
() -> {
377+
final DynamicClassDetails classDetails = new DynamicClassDetails(
378+
"Entity6",
379+
modelBuildingContext
380+
);
381+
final EntityJpaAnnotation entityUsage = (EntityJpaAnnotation) classDetails.applyAnnotationUsage(
382+
JpaAnnotations.ENTITY,
383+
modelBuildingContext
384+
);
385+
entityUsage.name( "Entity6" );
386+
387+
final DynamicFieldDetails idMember = classDetails.applyAttribute(
388+
"id",
389+
classDetailsRegistry.resolveClassDetails( Integer.class.getName() ),
390+
false,
391+
false,
392+
modelBuildingContext
393+
);
394+
idMember.applyAnnotationUsage( JpaAnnotations.ID, modelBuildingContext );
395+
396+
final DynamicFieldDetails nameMember = classDetails.applyAttribute(
397+
"name",
398+
classDetailsRegistry.resolveClassDetails( String.class.getName() ),
399+
false,
400+
false,
401+
modelBuildingContext
402+
);
403+
nameMember.applyAnnotationUsage( HibernateAnnotations.NATIONALIZED, modelBuildingContext );
404+
405+
return classDetails;
406+
}
340407
);
341408
contributions.contributeManagedClass( entity6Details );
342409
}

0 commit comments

Comments
 (0)