HHH-18520 Fix issue with dynamic model
This commit is contained in:
parent
92c434dd9b
commit
53f9321cc0
|
@ -8,6 +8,7 @@ package org.hibernate.boot.model.internal;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.annotations.Target;
|
import org.hibernate.annotations.Target;
|
||||||
|
import org.hibernate.boot.models.internal.ModelsHelper;
|
||||||
import org.hibernate.boot.spi.AccessType;
|
import org.hibernate.boot.spi.AccessType;
|
||||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.boot.spi.PropertyData;
|
import org.hibernate.boot.spi.PropertyData;
|
||||||
|
@ -87,8 +88,11 @@ public class PropertyInferredData implements PropertyData {
|
||||||
if ( targetAnnotation != null ) {
|
if ( targetAnnotation != null ) {
|
||||||
final String targetName = targetAnnotation.value();
|
final String targetName = targetAnnotation.value();
|
||||||
final SourceModelBuildingContext sourceModelBuildingContext = sourceModelContext;
|
final SourceModelBuildingContext sourceModelBuildingContext = sourceModelContext;
|
||||||
final ClassDetails classDetails = sourceModelBuildingContext.getClassDetailsRegistry()
|
final ClassDetails classDetails = ModelsHelper.resolveClassDetails(
|
||||||
.resolveClassDetails( targetName );
|
targetName,
|
||||||
|
sourceModelBuildingContext.getClassDetailsRegistry(),
|
||||||
|
() -> new DynamicClassDetails( targetName, sourceModelContext )
|
||||||
|
);
|
||||||
return new ClassTypeDetailsImpl( classDetails, TypeDetails.Kind.CLASS );
|
return new ClassTypeDetailsImpl( classDetails, TypeDetails.Kind.CLASS );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,8 +121,11 @@ public class PropertyInferredData implements PropertyData {
|
||||||
final org.hibernate.boot.internal.Target annotationUsage = propertyMember.getDirectAnnotationUsage( org.hibernate.boot.internal.Target.class );
|
final org.hibernate.boot.internal.Target annotationUsage = propertyMember.getDirectAnnotationUsage( org.hibernate.boot.internal.Target.class );
|
||||||
if ( annotationUsage != null ) {
|
if ( annotationUsage != null ) {
|
||||||
final String targetName = annotationUsage.value();
|
final String targetName = annotationUsage.value();
|
||||||
final ClassDetails classDetails = sourceModelBuildingContext.getClassDetailsRegistry()
|
final ClassDetails classDetails = ModelsHelper.resolveClassDetails(
|
||||||
.resolveClassDetails( targetName );
|
targetName,
|
||||||
|
sourceModelBuildingContext.getClassDetailsRegistry(),
|
||||||
|
() -> new DynamicClassDetails( targetName, sourceModelBuildingContext )
|
||||||
|
);
|
||||||
return new ClassTypeDetailsImpl( classDetails, TypeDetails.Kind.CLASS );
|
return new ClassTypeDetailsImpl( classDetails, TypeDetails.Kind.CLASS );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,4 +176,6 @@ public class PropertyInferredData implements PropertyData {
|
||||||
public ClassDetails getDeclaringClass() {
|
public ClassDetails getDeclaringClass() {
|
||||||
return declaringClass;
|
return declaringClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,15 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.boot.models.internal;
|
package org.hibernate.boot.models.internal;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.hibernate.annotations.TenantId;
|
import org.hibernate.annotations.TenantId;
|
||||||
|
import org.hibernate.models.internal.MutableClassDetailsRegistry;
|
||||||
import org.hibernate.models.internal.jdk.JdkBuilders;
|
import org.hibernate.models.internal.jdk.JdkBuilders;
|
||||||
|
import org.hibernate.models.jandex.internal.JandexClassDetails;
|
||||||
import org.hibernate.models.jandex.spi.JandexModelBuildingContext;
|
import org.hibernate.models.jandex.spi.JandexModelBuildingContext;
|
||||||
import org.hibernate.models.spi.AnnotationDescriptorRegistry;
|
import org.hibernate.models.spi.AnnotationDescriptorRegistry;
|
||||||
|
import org.hibernate.models.spi.ClassDetails;
|
||||||
import org.hibernate.models.spi.ClassDetailsRegistry;
|
import org.hibernate.models.spi.ClassDetailsRegistry;
|
||||||
import org.hibernate.models.spi.RegistryPrimer;
|
import org.hibernate.models.spi.RegistryPrimer;
|
||||||
import org.hibernate.models.spi.SourceModelBuildingContext;
|
import org.hibernate.models.spi.SourceModelBuildingContext;
|
||||||
|
@ -51,8 +56,26 @@ public class ModelsHelper {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
classDetailsRegistry.resolveClassDetails( className );
|
resolveClassDetails(
|
||||||
|
className,
|
||||||
|
classDetailsRegistry,
|
||||||
|
() -> new JandexClassDetails( knownClass, buildingContext )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ClassDetails resolveClassDetails(
|
||||||
|
String className,
|
||||||
|
ClassDetailsRegistry classDetailsRegistry,
|
||||||
|
Supplier<ClassDetails> classDetailsSupplier) {
|
||||||
|
ClassDetails classDetails = classDetailsRegistry.findClassDetails( className );
|
||||||
|
if ( classDetails != null ) {
|
||||||
|
return classDetails;
|
||||||
|
}
|
||||||
|
classDetails = classDetailsSupplier.get();
|
||||||
|
classDetailsRegistry.as( MutableClassDetailsRegistry.class )
|
||||||
|
.addClassDetails( className, classDetails );
|
||||||
|
return classDetails;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.boot.models.annotations.internal.AttributeAccessorAnnotatio
|
||||||
import org.hibernate.boot.models.annotations.internal.CacheAnnotation;
|
import org.hibernate.boot.models.annotations.internal.CacheAnnotation;
|
||||||
import org.hibernate.boot.models.annotations.internal.CacheableJpaAnnotation;
|
import org.hibernate.boot.models.annotations.internal.CacheableJpaAnnotation;
|
||||||
import org.hibernate.boot.models.annotations.internal.ExtendsXmlAnnotation;
|
import org.hibernate.boot.models.annotations.internal.ExtendsXmlAnnotation;
|
||||||
|
import org.hibernate.boot.models.internal.ModelsHelper;
|
||||||
import org.hibernate.boot.models.xml.internal.attr.BasicAttributeProcessing;
|
import org.hibernate.boot.models.xml.internal.attr.BasicAttributeProcessing;
|
||||||
import org.hibernate.boot.models.xml.internal.attr.BasicIdAttributeProcessing;
|
import org.hibernate.boot.models.xml.internal.attr.BasicIdAttributeProcessing;
|
||||||
import org.hibernate.boot.models.xml.internal.attr.CommonAttributeProcessing;
|
import org.hibernate.boot.models.xml.internal.attr.CommonAttributeProcessing;
|
||||||
|
@ -100,7 +101,19 @@ public class ManagedTypeProcessor {
|
||||||
|
|
||||||
memberAdjuster = ManagedTypeProcessor::adjustDynamicTypeMember;
|
memberAdjuster = ManagedTypeProcessor::adjustDynamicTypeMember;
|
||||||
classAccessType = AccessType.FIELD;
|
classAccessType = AccessType.FIELD;
|
||||||
classDetails = (MutableClassDetails) classDetailsRegistry.resolveClassDetails( jaxbEntity.getName() );
|
classDetails = (MutableClassDetails) ModelsHelper.resolveClassDetails(
|
||||||
|
jaxbEntity.getName(),
|
||||||
|
classDetailsRegistry,
|
||||||
|
() ->
|
||||||
|
new DynamicClassDetails(
|
||||||
|
jaxbEntity.getName(),
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
xmlDocumentContext.getModelBuildingContext()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
prepareDynamicClass( classDetails, jaxbEntity, xmlDocumentContext );
|
prepareDynamicClass( classDetails, jaxbEntity, xmlDocumentContext );
|
||||||
}
|
}
|
||||||
|
@ -934,8 +947,15 @@ public class ManagedTypeProcessor {
|
||||||
throw new ModelsException( "Embeddable did not define class nor name" );
|
throw new ModelsException( "Embeddable did not define class nor name" );
|
||||||
}
|
}
|
||||||
// no class == dynamic...
|
// no class == dynamic...
|
||||||
classDetails = (MutableClassDetails) classDetailsRegistry
|
classDetails = (MutableClassDetails) ModelsHelper.resolveClassDetails(
|
||||||
.resolveClassDetails( jaxbEmbeddable.getName() );
|
jaxbEmbeddable.getName(),
|
||||||
|
classDetailsRegistry,
|
||||||
|
() ->
|
||||||
|
new DynamicClassDetails(
|
||||||
|
jaxbEmbeddable.getName(),
|
||||||
|
xmlDocumentContext.getModelBuildingContext()
|
||||||
|
)
|
||||||
|
);
|
||||||
classAccessType = AccessType.FIELD;
|
classAccessType = AccessType.FIELD;
|
||||||
memberAdjuster = ManagedTypeProcessor::adjustDynamicTypeMember;
|
memberAdjuster = ManagedTypeProcessor::adjustDynamicTypeMember;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedMapping;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeImpl;
|
||||||
|
import org.hibernate.boot.models.internal.ModelsHelper;
|
||||||
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
|
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
|
||||||
import org.hibernate.boot.spi.BootstrapContext;
|
import org.hibernate.boot.spi.BootstrapContext;
|
||||||
import org.hibernate.boot.spi.EffectiveMappingDefaults;
|
import org.hibernate.boot.spi.EffectiveMappingDefaults;
|
||||||
|
@ -137,8 +138,11 @@ public interface XmlDocumentContext {
|
||||||
// <embedded/>, <embedded-id/>
|
// <embedded/>, <embedded-id/>
|
||||||
final String target = jaxbEmbeddedMapping.getTarget();
|
final String target = jaxbEmbeddedMapping.getTarget();
|
||||||
if ( isNotEmpty( target ) ) {
|
if ( isNotEmpty( target ) ) {
|
||||||
return (MutableClassDetails) getModelBuildingContext().getClassDetailsRegistry()
|
return (MutableClassDetails) ModelsHelper.resolveClassDetails(
|
||||||
.resolveClassDetails( target );
|
target,
|
||||||
|
getModelBuildingContext().getClassDetailsRegistry(),
|
||||||
|
() -> new DynamicClassDetails( target, getModelBuildingContext() )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// fall through to exception
|
// fall through to exception
|
||||||
}
|
}
|
||||||
|
@ -146,8 +150,18 @@ public interface XmlDocumentContext {
|
||||||
if ( jaxbPersistentAttribute instanceof JaxbAssociationAttribute jaxbAssociationAttribute ) {
|
if ( jaxbPersistentAttribute instanceof JaxbAssociationAttribute jaxbAssociationAttribute ) {
|
||||||
final String target = jaxbAssociationAttribute.getTargetEntity();
|
final String target = jaxbAssociationAttribute.getTargetEntity();
|
||||||
if ( isNotEmpty( target ) ) {
|
if ( isNotEmpty( target ) ) {
|
||||||
return (MutableClassDetails) getModelBuildingContext().getClassDetailsRegistry()
|
return (MutableClassDetails) ModelsHelper.resolveClassDetails(
|
||||||
.resolveClassDetails( target );
|
target,
|
||||||
|
getModelBuildingContext().getClassDetailsRegistry(),
|
||||||
|
() -> new DynamicClassDetails(
|
||||||
|
target,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
getModelBuildingContext()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// fall through to exception
|
// fall through to exception
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,22 @@ import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.boot.ResourceStreamLocator;
|
import org.hibernate.boot.ResourceStreamLocator;
|
||||||
|
import org.hibernate.boot.models.HibernateAnnotations;
|
||||||
|
import org.hibernate.boot.models.JpaAnnotations;
|
||||||
|
import org.hibernate.boot.models.annotations.internal.EntityJpaAnnotation;
|
||||||
|
import org.hibernate.boot.models.internal.ModelsHelper;
|
||||||
import org.hibernate.boot.spi.AdditionalMappingContributions;
|
import org.hibernate.boot.spi.AdditionalMappingContributions;
|
||||||
import org.hibernate.boot.spi.AdditionalMappingContributor;
|
import org.hibernate.boot.spi.AdditionalMappingContributor;
|
||||||
import org.hibernate.boot.spi.InFlightMetadataCollector;
|
import org.hibernate.boot.spi.InFlightMetadataCollector;
|
||||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
import org.hibernate.models.internal.dynamic.DynamicClassDetails;
|
||||||
|
import org.hibernate.models.internal.dynamic.DynamicFieldDetails;
|
||||||
|
import org.hibernate.models.internal.jdk.JdkClassDetails;
|
||||||
import org.hibernate.models.spi.ClassDetails;
|
import org.hibernate.models.spi.ClassDetails;
|
||||||
import org.hibernate.models.spi.ClassDetailsRegistry;
|
import org.hibernate.models.spi.ClassDetailsRegistry;
|
||||||
|
import org.hibernate.models.spi.MutableMemberDetails;
|
||||||
|
import org.hibernate.models.spi.SourceModelBuildingContext;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
|
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry.JavaService;
|
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry.JavaService;
|
||||||
|
@ -292,28 +301,53 @@ public class AdditionalMappingContributorTests {
|
||||||
InFlightMetadataCollector metadata,
|
InFlightMetadataCollector metadata,
|
||||||
ResourceStreamLocator resourceStreamLocator,
|
ResourceStreamLocator resourceStreamLocator,
|
||||||
MetadataBuildingContext buildingContext) {
|
MetadataBuildingContext buildingContext) {
|
||||||
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getMetadataCollector()
|
SourceModelBuildingContext sourceModelBuildingContext = buildingContext.getMetadataCollector()
|
||||||
.getSourceModelBuildingContext()
|
.getSourceModelBuildingContext();
|
||||||
|
final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext
|
||||||
.getClassDetailsRegistry();
|
.getClassDetailsRegistry();
|
||||||
|
|
||||||
contributeEntity4Details( contributions, classDetailsRegistry );
|
contributeEntity4Details( contributions, sourceModelBuildingContext, classDetailsRegistry );
|
||||||
contributeEntity5Details( contributions, classDetailsRegistry );
|
contributeEntity5Details( contributions, sourceModelBuildingContext, classDetailsRegistry );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void contributeEntity4Details(
|
private static void contributeEntity4Details(
|
||||||
AdditionalMappingContributions contributions,
|
AdditionalMappingContributions contributions,
|
||||||
|
SourceModelBuildingContext sourceModelBuildingContext,
|
||||||
ClassDetailsRegistry classDetailsRegistry) {
|
ClassDetailsRegistry classDetailsRegistry) {
|
||||||
final ClassDetails entity4Details = classDetailsRegistry.resolveClassDetails(
|
final ClassDetails entity4Details = ModelsHelper.resolveClassDetails(
|
||||||
Entity4.class.getName()
|
Entity4.class.getName(),
|
||||||
|
classDetailsRegistry,
|
||||||
|
() ->
|
||||||
|
new JdkClassDetails( Entity4.class, sourceModelBuildingContext )
|
||||||
);
|
);
|
||||||
contributions.contributeManagedClass( entity4Details );
|
contributions.contributeManagedClass( entity4Details );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void contributeEntity5Details(
|
private static void contributeEntity5Details(
|
||||||
AdditionalMappingContributions contributions,
|
AdditionalMappingContributions contributions,
|
||||||
|
SourceModelBuildingContext modelBuildingContext,
|
||||||
ClassDetailsRegistry classDetailsRegistry) {
|
ClassDetailsRegistry classDetailsRegistry) {
|
||||||
final ClassDetails entity5Details = classDetailsRegistry.resolveClassDetails(
|
final ClassDetails entity5Details = ModelsHelper.resolveClassDetails(
|
||||||
Entity5.class.getName()
|
Entity5.class.getName(),
|
||||||
|
classDetailsRegistry,
|
||||||
|
() -> {
|
||||||
|
final JdkClassDetails jdkClassDetails = new JdkClassDetails(
|
||||||
|
Entity5.class,
|
||||||
|
modelBuildingContext
|
||||||
|
);
|
||||||
|
|
||||||
|
final EntityJpaAnnotation entityUsage = (EntityJpaAnnotation) jdkClassDetails.applyAnnotationUsage(
|
||||||
|
JpaAnnotations.ENTITY,
|
||||||
|
modelBuildingContext
|
||||||
|
);
|
||||||
|
entityUsage.name( "___Entity5___" );
|
||||||
|
|
||||||
|
final MutableMemberDetails idField = (MutableMemberDetails) jdkClassDetails.findFieldByName(
|
||||||
|
"id" );
|
||||||
|
idField.applyAnnotationUsage( JpaAnnotations.ID, modelBuildingContext );
|
||||||
|
|
||||||
|
return jdkClassDetails;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
contributions.contributeManagedClass( entity5Details );
|
contributions.contributeManagedClass( entity5Details );
|
||||||
}
|
}
|
||||||
|
@ -326,17 +360,50 @@ public class AdditionalMappingContributorTests {
|
||||||
InFlightMetadataCollector metadata,
|
InFlightMetadataCollector metadata,
|
||||||
ResourceStreamLocator resourceStreamLocator,
|
ResourceStreamLocator resourceStreamLocator,
|
||||||
MetadataBuildingContext buildingContext) {
|
MetadataBuildingContext buildingContext) {
|
||||||
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getMetadataCollector()
|
final SourceModelBuildingContext sourceModelBuildingContext = buildingContext.getMetadataCollector()
|
||||||
.getSourceModelBuildingContext()
|
.getSourceModelBuildingContext();
|
||||||
.getClassDetailsRegistry();
|
final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry();
|
||||||
contributeEntity6Details( contributions, classDetailsRegistry );
|
contributeEntity6Details( contributions, sourceModelBuildingContext, classDetailsRegistry );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void contributeEntity6Details(
|
private void contributeEntity6Details(
|
||||||
AdditionalMappingContributions contributions,
|
AdditionalMappingContributions contributions,
|
||||||
|
SourceModelBuildingContext modelBuildingContext,
|
||||||
ClassDetailsRegistry classDetailsRegistry) {
|
ClassDetailsRegistry classDetailsRegistry) {
|
||||||
final ClassDetails entity6Details = classDetailsRegistry.resolveClassDetails(
|
final ClassDetails entity6Details = ModelsHelper.resolveClassDetails(
|
||||||
"Entity6"
|
"Entity6",
|
||||||
|
classDetailsRegistry,
|
||||||
|
() -> {
|
||||||
|
final DynamicClassDetails classDetails = new DynamicClassDetails(
|
||||||
|
"Entity6",
|
||||||
|
modelBuildingContext
|
||||||
|
);
|
||||||
|
final EntityJpaAnnotation entityUsage = (EntityJpaAnnotation) classDetails.applyAnnotationUsage(
|
||||||
|
JpaAnnotations.ENTITY,
|
||||||
|
modelBuildingContext
|
||||||
|
);
|
||||||
|
entityUsage.name( "Entity6" );
|
||||||
|
|
||||||
|
final DynamicFieldDetails idMember = classDetails.applyAttribute(
|
||||||
|
"id",
|
||||||
|
classDetailsRegistry.resolveClassDetails( Integer.class.getName() ),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
modelBuildingContext
|
||||||
|
);
|
||||||
|
idMember.applyAnnotationUsage( JpaAnnotations.ID, modelBuildingContext );
|
||||||
|
|
||||||
|
final DynamicFieldDetails nameMember = classDetails.applyAttribute(
|
||||||
|
"name",
|
||||||
|
classDetailsRegistry.resolveClassDetails( String.class.getName() ),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
modelBuildingContext
|
||||||
|
);
|
||||||
|
nameMember.applyAnnotationUsage( HibernateAnnotations.NATIONALIZED, modelBuildingContext );
|
||||||
|
|
||||||
|
return classDetails;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
contributions.contributeManagedClass( entity6Details );
|
contributions.contributeManagedClass( entity6Details );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue