HHH-18062 Fix id-class record instantiation and mapper component
This commit is contained in:
parent
996783c380
commit
677c8b6529
|
@ -495,7 +495,7 @@ public class EntityBinder {
|
||||||
else {
|
else {
|
||||||
final boolean ignoreIdAnnotations = isIgnoreIdAnnotations();
|
final boolean ignoreIdAnnotations = isIgnoreIdAnnotations();
|
||||||
setIgnoreIdAnnotations( true );
|
setIgnoreIdAnnotations( true );
|
||||||
bindIdClass(
|
final Component idClassComponent = bindIdClass(
|
||||||
inferredData,
|
inferredData,
|
||||||
baseInferredData,
|
baseInferredData,
|
||||||
propertyHolder,
|
propertyHolder,
|
||||||
|
@ -514,6 +514,9 @@ public class EntityBinder {
|
||||||
propertyAccessor,
|
propertyAccessor,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
if ( idClassComponent.isSimpleRecord() ) {
|
||||||
|
mapper.setSimpleRecord( true );
|
||||||
|
}
|
||||||
setIgnoreIdAnnotations( ignoreIdAnnotations );
|
setIgnoreIdAnnotations( ignoreIdAnnotations );
|
||||||
for ( Property property : mapper.getProperties() ) {
|
for ( Property property : mapper.getProperties() ) {
|
||||||
idPropertiesIfIdClass.add( property.getName() );
|
idPropertiesIfIdClass.add( property.getName() );
|
||||||
|
@ -656,7 +659,7 @@ public class EntityBinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindIdClass(
|
private Component bindIdClass(
|
||||||
PropertyData inferredData,
|
PropertyData inferredData,
|
||||||
PropertyData baseInferredData,
|
PropertyData baseInferredData,
|
||||||
PropertyHolder propertyHolder,
|
PropertyHolder propertyHolder,
|
||||||
|
@ -707,6 +710,8 @@ public class EntityBinder {
|
||||||
rootClass.setEmbeddedIdentifier( inferredData.getPropertyClass() == null );
|
rootClass.setEmbeddedIdentifier( inferredData.getPropertyClass() == null );
|
||||||
|
|
||||||
propertyHolder.setInIdClass( null );
|
propertyHolder.setInIdClass( null );
|
||||||
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void handleIdGenerator(PropertyData inferredData, MetadataBuildingContext buildingContext, Component id) {
|
private static void handleIdGenerator(PropertyData inferredData, MetadataBuildingContext buildingContext, Component id) {
|
||||||
|
|
|
@ -108,6 +108,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
||||||
private QualifiedName structName;
|
private QualifiedName structName;
|
||||||
private String[] structColumnNames;
|
private String[] structColumnNames;
|
||||||
private transient Class<?> componentClass;
|
private transient Class<?> componentClass;
|
||||||
|
private transient Boolean simpleRecord;
|
||||||
|
|
||||||
private transient Generator builtIdentifierGenerator;
|
private transient Generator builtIdentifierGenerator;
|
||||||
|
|
||||||
|
@ -377,6 +378,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
||||||
public void setComponentClassName(String componentClass) {
|
public void setComponentClassName(String componentClass) {
|
||||||
this.componentClassName = componentClass;
|
this.componentClassName = componentClass;
|
||||||
this.componentClass = null;
|
this.componentClass = null;
|
||||||
|
this.simpleRecord = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmbedded(boolean embedded) {
|
public void setEmbedded(boolean embedded) {
|
||||||
|
@ -899,26 +901,33 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
||||||
return this.originalPropertyOrder = originalPropertyOrder;
|
return this.originalPropertyOrder = originalPropertyOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSimpleRecord() {
|
public void setSimpleRecord(boolean simpleRecord) {
|
||||||
// A simple record is given, when the properties match the order of the record component names
|
this.simpleRecord = simpleRecord;
|
||||||
final Class<?> componentClass = resolveComponentClass();
|
}
|
||||||
if ( customInstantiator != null ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( componentClass == null || !ReflectHelper.isRecord( componentClass ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final String[] recordComponentNames = ReflectHelper.getRecordComponentNames( componentClass );
|
|
||||||
if ( recordComponentNames.length != properties.size() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for ( int i = 0; i < recordComponentNames.length; i++ ) {
|
|
||||||
if ( !recordComponentNames[i].equals( properties.get( i ).getName() ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
public boolean isSimpleRecord() {
|
||||||
|
Boolean simple = simpleRecord;
|
||||||
|
if ( simple == null ) {
|
||||||
|
// A simple record is given, when the properties match the order of the record component names
|
||||||
|
final Class<?> componentClass = resolveComponentClass();
|
||||||
|
if ( customInstantiator != null ) {
|
||||||
|
return simpleRecord = false;
|
||||||
|
}
|
||||||
|
if ( componentClass == null || !ReflectHelper.isRecord( componentClass ) ) {
|
||||||
|
return simpleRecord = false;
|
||||||
|
}
|
||||||
|
final String[] recordComponentNames = ReflectHelper.getRecordComponentNames( componentClass );
|
||||||
|
if ( recordComponentNames.length != properties.size() ) {
|
||||||
|
return simpleRecord = false;
|
||||||
|
}
|
||||||
|
for ( int i = 0; i < recordComponentNames.length; i++ ) {
|
||||||
|
if ( !recordComponentNames[i].equals( properties.get( i ).getName() ) ) {
|
||||||
|
return simpleRecord = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
simple = simpleRecord = true;
|
||||||
|
}
|
||||||
|
return simple;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<? extends EmbeddableInstantiator> getCustomInstantiator() {
|
public Class<? extends EmbeddableInstantiator> getCustomInstantiator() {
|
||||||
|
|
|
@ -74,7 +74,11 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
.getJavaTypeRegistry()
|
.getJavaTypeRegistry()
|
||||||
.resolveManagedTypeDescriptor( idClassSource.getComponentClass() );
|
.resolveManagedTypeDescriptor( idClassSource.getComponentClass() );
|
||||||
|
|
||||||
this.representationStrategy = new IdClassRepresentationStrategy( this );
|
this.representationStrategy = new IdClassRepresentationStrategy(
|
||||||
|
this,
|
||||||
|
idClassSource.sortProperties() == null,
|
||||||
|
idClassSource::getPropertyNames
|
||||||
|
);
|
||||||
|
|
||||||
final PropertyAccess propertyAccess = PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess(
|
final PropertyAccess propertyAccess = PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess(
|
||||||
null,
|
null,
|
||||||
|
@ -101,7 +105,7 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
propertyAccess
|
propertyAccess
|
||||||
);
|
);
|
||||||
|
|
||||||
final CompositeType idClassType = (CompositeType) idClassSource.getType();
|
final CompositeType idClassType = idClassSource.getType();
|
||||||
( (CompositeTypeImplementor) idClassType ).injectMappingModelPart( embedded, creationProcess );
|
( (CompositeTypeImplementor) idClassType ).injectMappingModelPart( embedded, creationProcess );
|
||||||
|
|
||||||
creationProcess.registerInitializationCallback(
|
creationProcess.registerInitializationCallback(
|
||||||
|
@ -127,10 +131,16 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
super( new MutableAttributeMappingList( inverseMappingType.attributeMappings.size() ) );
|
super( new MutableAttributeMappingList( inverseMappingType.attributeMappings.size() ) );
|
||||||
|
|
||||||
this.navigableRole = inverseMappingType.getNavigableRole();
|
this.navigableRole = inverseMappingType.getNavigableRole();
|
||||||
this.idMapping = (NonAggregatedIdentifierMapping) valueMapping;;
|
this.idMapping = (NonAggregatedIdentifierMapping) valueMapping;
|
||||||
this.virtualIdEmbeddable = (VirtualIdEmbeddable) valueMapping.getEmbeddableTypeDescriptor();
|
this.virtualIdEmbeddable = (VirtualIdEmbeddable) valueMapping.getEmbeddableTypeDescriptor();
|
||||||
this.javaType = inverseMappingType.javaType;
|
this.javaType = inverseMappingType.javaType;
|
||||||
this.representationStrategy = new IdClassRepresentationStrategy( this );
|
this.representationStrategy = new IdClassRepresentationStrategy( this, false, () -> {
|
||||||
|
final String[] attributeNames = new String[inverseMappingType.getNumberOfAttributeMappings()];
|
||||||
|
for ( int i = 0; i < attributeNames.length; i++ ) {
|
||||||
|
attributeNames[i] = inverseMappingType.getAttributeMapping( i ).getAttributeName();
|
||||||
|
}
|
||||||
|
return attributeNames;
|
||||||
|
} );
|
||||||
this.embedded = valueMapping;
|
this.embedded = valueMapping;
|
||||||
this.selectableMappings = selectableMappings;
|
this.selectableMappings = selectableMappings;
|
||||||
creationProcess.registerInitializationCallback(
|
creationProcess.registerInitializationCallback(
|
||||||
|
|
|
@ -7,12 +7,14 @@
|
||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
import org.hibernate.metamodel.RepresentationMode;
|
import org.hibernate.metamodel.RepresentationMode;
|
||||||
import org.hibernate.metamodel.internal.EmbeddableInstantiatorPojoStandard;
|
import org.hibernate.metamodel.internal.EmbeddableInstantiatorPojoStandard;
|
||||||
|
import org.hibernate.metamodel.internal.EmbeddableInstantiatorRecordIndirecting;
|
||||||
import org.hibernate.metamodel.internal.EmbeddableInstantiatorRecordStandard;
|
import org.hibernate.metamodel.internal.EmbeddableInstantiatorRecordStandard;
|
||||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||||
|
@ -29,11 +31,29 @@ public class IdClassRepresentationStrategy implements EmbeddableRepresentationSt
|
||||||
private final JavaType<?> idClassType;
|
private final JavaType<?> idClassType;
|
||||||
private final EmbeddableInstantiator instantiator;
|
private final EmbeddableInstantiator instantiator;
|
||||||
|
|
||||||
public IdClassRepresentationStrategy(IdClassEmbeddable idClassEmbeddable) {
|
public IdClassRepresentationStrategy(
|
||||||
|
IdClassEmbeddable idClassEmbeddable,
|
||||||
|
boolean simplePropertyOrder,
|
||||||
|
Supplier<String[]> attributeNamesAccess) {
|
||||||
this.idClassType = idClassEmbeddable.getMappedJavaType();
|
this.idClassType = idClassEmbeddable.getMappedJavaType();
|
||||||
this.instantiator = isRecord( idClassType.getJavaTypeClass() ) ?
|
final Class<?> javaTypeClass = idClassType.getJavaTypeClass();
|
||||||
new EmbeddableInstantiatorRecordStandard( idClassType.getJavaTypeClass() ) :
|
if ( isRecord( javaTypeClass ) ) {
|
||||||
new EmbeddableInstantiatorPojoStandard( idClassType.getJavaTypeClass(), () -> idClassEmbeddable );
|
if ( simplePropertyOrder ) {
|
||||||
|
this.instantiator = new EmbeddableInstantiatorRecordStandard( javaTypeClass );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.instantiator = EmbeddableInstantiatorRecordIndirecting.of(
|
||||||
|
javaTypeClass,
|
||||||
|
attributeNamesAccess.get()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.instantiator = new EmbeddableInstantiatorPojoStandard(
|
||||||
|
idClassType.getJavaTypeClass(),
|
||||||
|
() -> idClassEmbeddable
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue