HHH-18062 Fix id-class record instantiation and mapper component
This commit is contained in:
parent
24e015237c
commit
6bf3f15af3
|
@ -493,7 +493,7 @@ public class EntityBinder {
|
|||
else {
|
||||
final boolean ignoreIdAnnotations = isIgnoreIdAnnotations();
|
||||
setIgnoreIdAnnotations( true );
|
||||
bindIdClass(
|
||||
final Component idClassComponent = bindIdClass(
|
||||
inferredData,
|
||||
baseInferredData,
|
||||
propertyHolder,
|
||||
|
@ -512,6 +512,9 @@ public class EntityBinder {
|
|||
propertyAccessor,
|
||||
true
|
||||
);
|
||||
if ( idClassComponent.isSimpleRecord() ) {
|
||||
mapper.setSimpleRecord( true );
|
||||
}
|
||||
setIgnoreIdAnnotations( ignoreIdAnnotations );
|
||||
for ( Property property : mapper.getProperties() ) {
|
||||
idPropertiesIfIdClass.add( property.getName() );
|
||||
|
@ -654,7 +657,7 @@ public class EntityBinder {
|
|||
}
|
||||
}
|
||||
|
||||
private void bindIdClass(
|
||||
private Component bindIdClass(
|
||||
PropertyData inferredData,
|
||||
PropertyData baseInferredData,
|
||||
PropertyHolder propertyHolder,
|
||||
|
@ -705,6 +708,8 @@ public class EntityBinder {
|
|||
rootClass.setEmbeddedIdentifier( inferredData.getPropertyClass() == null );
|
||||
|
||||
propertyHolder.setInIdClass( null );
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private static void handleIdGenerator(PropertyData inferredData, MetadataBuildingContext buildingContext, Component id) {
|
||||
|
|
|
@ -89,6 +89,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
private AggregateColumn parentAggregateColumn;
|
||||
private String structName;
|
||||
private String[] structColumnNames;
|
||||
private transient Boolean simpleRecord;
|
||||
// lazily computed based on 'properties' field: invalidate by setting to null when properties are modified
|
||||
private transient List<Selectable> cachedSelectables;
|
||||
// lazily computed based on 'properties' field: invalidate by setting to null when properties are modified
|
||||
|
@ -315,6 +316,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
|
||||
public void setComponentClassName(String componentClass) {
|
||||
this.componentClassName = componentClass;
|
||||
this.simpleRecord = null;
|
||||
}
|
||||
|
||||
public void setEmbedded(boolean embedded) {
|
||||
|
@ -777,26 +779,33 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
return this.originalPropertyOrder = originalPropertyOrder;
|
||||
}
|
||||
|
||||
private boolean isSimpleRecord() {
|
||||
// A simple record is given, when the properties match the order of the record component names
|
||||
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;
|
||||
}
|
||||
}
|
||||
public void setSimpleRecord(boolean simpleRecord) {
|
||||
this.simpleRecord = simpleRecord;
|
||||
}
|
||||
|
||||
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() {
|
||||
|
|
|
@ -74,7 +74,11 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
|||
.getJavaTypeRegistry()
|
||||
.resolveManagedTypeDescriptor( idClassSource.getComponentClass() );
|
||||
|
||||
this.representationStrategy = new IdClassRepresentationStrategy( this );
|
||||
this.representationStrategy = new IdClassRepresentationStrategy(
|
||||
this,
|
||||
idClassSource.sortProperties() == null,
|
||||
idClassSource::getPropertyNames
|
||||
);
|
||||
|
||||
final PropertyAccess propertyAccess = PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess(
|
||||
null,
|
||||
|
@ -101,7 +105,7 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
|||
propertyAccess
|
||||
);
|
||||
|
||||
final CompositeType idClassType = (CompositeType) idClassSource.getType();
|
||||
final CompositeType idClassType = idClassSource.getType();
|
||||
( (CompositeTypeImplementor) idClassType ).injectMappingModelPart( embedded, creationProcess );
|
||||
|
||||
creationProcess.registerInitializationCallback(
|
||||
|
@ -127,10 +131,16 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
|||
super( new MutableAttributeMappingList( inverseMappingType.attributeMappings.size() ) );
|
||||
|
||||
this.navigableRole = inverseMappingType.getNavigableRole();
|
||||
this.idMapping = (NonAggregatedIdentifierMapping) valueMapping;;
|
||||
this.idMapping = (NonAggregatedIdentifierMapping) valueMapping;
|
||||
this.virtualIdEmbeddable = (VirtualIdEmbeddable) valueMapping.getEmbeddableTypeDescriptor();
|
||||
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.selectableMappings = selectableMappings;
|
||||
creationProcess.registerInitializationCallback(
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
import org.hibernate.metamodel.internal.EmbeddableInstantiatorPojoStandard;
|
||||
import org.hibernate.metamodel.internal.EmbeddableInstantiatorRecordIndirecting;
|
||||
import org.hibernate.metamodel.internal.EmbeddableInstantiatorRecordStandard;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
|
@ -29,11 +31,29 @@ public class IdClassRepresentationStrategy implements EmbeddableRepresentationSt
|
|||
private final JavaType<?> idClassType;
|
||||
private final EmbeddableInstantiator instantiator;
|
||||
|
||||
public IdClassRepresentationStrategy(IdClassEmbeddable idClassEmbeddable) {
|
||||
public IdClassRepresentationStrategy(
|
||||
IdClassEmbeddable idClassEmbeddable,
|
||||
boolean simplePropertyOrder,
|
||||
Supplier<String[]> attributeNamesAccess) {
|
||||
this.idClassType = idClassEmbeddable.getMappedJavaType();
|
||||
this.instantiator = isRecord( idClassType.getJavaTypeClass() ) ?
|
||||
new EmbeddableInstantiatorRecordStandard( idClassType.getJavaTypeClass() ) :
|
||||
new EmbeddableInstantiatorPojoStandard( idClassType, () -> idClassEmbeddable );
|
||||
final Class<?> javaTypeClass = idClassType.getJavaTypeClass();
|
||||
if ( isRecord( javaTypeClass ) ) {
|
||||
if ( simplePropertyOrder ) {
|
||||
this.instantiator = new EmbeddableInstantiatorRecordStandard( javaTypeClass );
|
||||
}
|
||||
else {
|
||||
this.instantiator = EmbeddableInstantiatorRecordIndirecting.of(
|
||||
javaTypeClass,
|
||||
attributeNamesAccess.get()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.instantiator = new EmbeddableInstantiatorPojoStandard(
|
||||
idClassType,
|
||||
() -> idClassEmbeddable
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue