Introduce `VirtualIdEmbeddable` and `IdClassEmbeddable`
EmbeddableInstantiator Still need to - integrate EmbeddableInstantiator work - integrate embedded forms. `VirtualIdEmbeddable` does not really need it as it can use the id-mapping itself as the embedded form. But `IdClassEmbedded` should really be integrated - integrate `VirtualKeyEmbeddable` and `VirtualKeyEmbedded` for use as inverse composite fks - share `#finishInit` handling for `EmbeddableMappingType`, `VirtualIdEmbeddable` and `IdClassEmbeddable`
This commit is contained in:
parent
546a635be9
commit
0322d8fa84
|
@ -8,64 +8,45 @@ package org.hibernate.bytecode.spi;
|
|||
|
||||
/**
|
||||
* Represents reflection optimization for a particular class.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ReflectionOptimizer {
|
||||
/**
|
||||
* Retrieve the optimizer for calling an entity's constructor via reflection.
|
||||
*
|
||||
* @return The optimizer for instantiation
|
||||
*/
|
||||
public InstantiationOptimizer getInstantiationOptimizer();
|
||||
InstantiationOptimizer getInstantiationOptimizer();
|
||||
|
||||
/**
|
||||
* Retrieve the optimizer for accessing the entity's persistent state.
|
||||
*
|
||||
* @return The optimizer for persistent state access
|
||||
*/
|
||||
public AccessOptimizer getAccessOptimizer();
|
||||
AccessOptimizer getAccessOptimizer();
|
||||
|
||||
/**
|
||||
* Represents optimized entity instantiation.
|
||||
*/
|
||||
public static interface InstantiationOptimizer {
|
||||
interface InstantiationOptimizer {
|
||||
/**
|
||||
* Perform instantiation of an instance of the underlying class.
|
||||
*
|
||||
* @return The new instance.
|
||||
*/
|
||||
public Object newInstance();
|
||||
Object newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents optimized entity property access.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AccessOptimizer {
|
||||
interface AccessOptimizer {
|
||||
/**
|
||||
* Get the name of all properties.
|
||||
*
|
||||
* @return The name of all properties.
|
||||
*/
|
||||
public String[] getPropertyNames();
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Get the value of all properties from the given entity
|
||||
*
|
||||
* @param object The entity from which to extract values.
|
||||
*
|
||||
* @return The values.
|
||||
*/
|
||||
public Object[] getPropertyValues(Object object);
|
||||
Object[] getPropertyValues(Object object);
|
||||
|
||||
/**
|
||||
* Set all property values into an entity instance.
|
||||
*
|
||||
* @param object The entity instance
|
||||
* @param values The values to inject
|
||||
*/
|
||||
public void setPropertyValues(Object object, Object[] values);
|
||||
void setPropertyValues(Object object, Object[] values);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,15 @@
|
|||
package org.hibernate.loader;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PropertyPath {
|
||||
public static final String IDENTIFIER_MAPPER_PROPERTY = "_identifierMapper";
|
||||
public static final String IDENTIFIER_MAPPER_PROPERTY = NavigablePath.IDENTIFIER_MAPPER_PROPERTY;
|
||||
|
||||
|
||||
private final PropertyPath parent;
|
||||
private final String property;
|
||||
private final String fullPath;
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.metamodel.internal;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
|
@ -17,21 +18,25 @@ import static org.hibernate.bytecode.spi.ReflectionOptimizer.InstantiationOptimi
|
|||
/**
|
||||
* Support for instantiating embeddables as POJO representation
|
||||
* using bytecode optimizer
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EmbeddableInstantiatorPojoOptimized extends AbstractPojoInstantiator implements EmbeddableInstantiator {
|
||||
private final Supplier<EmbeddableMappingType> embeddableMappingAccess;
|
||||
private final InstantiationOptimizer instantiationOptimizer;
|
||||
|
||||
public EmbeddableInstantiatorPojoOptimized(
|
||||
JavaType<?> javaTypeDescriptor,
|
||||
Supplier<EmbeddableMappingType> embeddableMappingAccess,
|
||||
InstantiationOptimizer instantiationOptimizer) {
|
||||
super( javaTypeDescriptor.getJavaTypeClass() );
|
||||
this.embeddableMappingAccess = embeddableMappingAccess;
|
||||
this.instantiationOptimizer = instantiationOptimizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiate(Supplier<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory) {
|
||||
return instantiationOptimizer.newInstance();
|
||||
final Object embeddable = instantiationOptimizer.newInstance();
|
||||
final EmbeddableMappingType embeddableMapping = embeddableMappingAccess.get();
|
||||
embeddableMapping.setPropertyValues( embeddable, valuesAccess.get() );
|
||||
return embeddable;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.lang.reflect.Constructor;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.InstantiationException;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.PropertyNotFoundException;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
@ -22,18 +21,15 @@ import org.hibernate.type.descriptor.java.JavaType;
|
|||
|
||||
/**
|
||||
* Support for instantiating embeddables as POJO representation
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EmbeddableInstantiatorPojoStandard extends AbstractPojoInstantiator implements EmbeddableInstantiator {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoInstantiatorImpl.class );
|
||||
|
||||
private final Supplier<EmbeddableMappingType> embeddableMappingAccess;
|
||||
private final boolean constructorInjection = false;
|
||||
private final Constructor<?> constructor;
|
||||
|
||||
public EmbeddableInstantiatorPojoStandard(
|
||||
Supplier<EmbeddableMappingType> embeddableMappingAccess,
|
||||
JavaType<?> javaTypeDescriptor) {
|
||||
public EmbeddableInstantiatorPojoStandard(JavaType<?> javaTypeDescriptor, Supplier<EmbeddableMappingType> embeddableMappingAccess) {
|
||||
super( javaTypeDescriptor.getJavaTypeClass() );
|
||||
|
||||
this.embeddableMappingAccess = embeddableMappingAccess;
|
||||
|
@ -54,29 +50,29 @@ public class EmbeddableInstantiatorPojoStandard extends AbstractPojoInstantiator
|
|||
@Override
|
||||
public Object instantiate(Supplier<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory) {
|
||||
if ( isAbstract() ) {
|
||||
throw new InstantiationException( "Cannot instantiate abstract class or interface: ", getMappedPojoClass() );
|
||||
throw new InstantiationException(
|
||||
"Cannot instantiate abstract class or interface: ", getMappedPojoClass()
|
||||
);
|
||||
}
|
||||
|
||||
if ( constructor == null ) {
|
||||
throw new InstantiationException( "No default constructor for embeddable: ", getMappedPojoClass() );
|
||||
}
|
||||
|
||||
if ( valuesAccess != null ) {
|
||||
if ( constructor.getParameterTypes().length > 0 ) {
|
||||
// constructor injection
|
||||
throw new NotYetImplementedFor6Exception( "Constructor injection for embeddables not yet implemented" );
|
||||
}
|
||||
throw new InstantiationException( "Unable to locate constructor for embeddable", getMappedPojoClass() );
|
||||
}
|
||||
|
||||
try {
|
||||
if ( constructorInjection ) {
|
||||
return constructor.newInstance( valuesAccess.get() );
|
||||
}
|
||||
|
||||
final Object instance = constructor.newInstance();
|
||||
if ( valuesAccess != null ) {
|
||||
embeddableMappingAccess.get().setPropertyValues( instance, valuesAccess.get() );
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new InstantiationException( "Could not instantiate embeddable: ", getMappedPojoClass(), e );
|
||||
throw new InstantiationException( "Could not instantiate entity: ", getMappedPojoClass(), e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,14 +75,12 @@ public class EmbeddableRepresentationStrategyPojo extends AbstractEmbeddableRepr
|
|||
final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer();
|
||||
return new EmbeddableInstantiatorPojoOptimized(
|
||||
getEmbeddableJavaTypeDescriptor(),
|
||||
runtimeDescriptorAccess,
|
||||
instantiationOptimizer
|
||||
);
|
||||
}
|
||||
|
||||
return new EmbeddableInstantiatorPojoStandard(
|
||||
runtimeDescriptorAccess,
|
||||
getEmbeddableJavaTypeDescriptor()
|
||||
);
|
||||
return new EmbeddableInstantiatorPojoStandard( getEmbeddableJavaTypeDescriptor(), runtimeDescriptorAccess );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
|
|||
import org.hibernate.metamodel.mapping.MappingModelCreationLogger;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping.IdentifierValueMapper;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
|
@ -50,7 +51,6 @@ import org.hibernate.metamodel.mapping.SelectableMappings;
|
|||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping.IdentifierValueMapper;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.hibernate.property.access.spi.PropertyAccess;
|
|||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
* EmbeddableRepresentationStrategy for an IdClass mapping
|
||||
*/
|
||||
public class IdClassRepresentationStrategy implements EmbeddableRepresentationStrategy {
|
||||
private final JavaType<?> idClassType;
|
||||
|
@ -25,7 +25,7 @@ public class IdClassRepresentationStrategy implements EmbeddableRepresentationSt
|
|||
|
||||
public IdClassRepresentationStrategy(IdClassEmbeddable idClassEmbeddable) {
|
||||
this.idClassType = idClassEmbeddable.getMappedJavaTypeDescriptor();
|
||||
this.instantiator = new EmbeddableInstantiatorPojoStandard( () -> idClassEmbeddable, idClassType );
|
||||
this.instantiator = new EmbeddableInstantiatorPojoStandard( idClassType, () -> idClassEmbeddable );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,9 +18,9 @@ import org.hibernate.mapping.Component;
|
|||
import org.hibernate.mapping.RootClass;
|
||||
import org.hibernate.metamodel.internal.AbstractCompositeIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Objects;
|
|||
|
||||
import org.hibernate.query.DotIdentifierSequence;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
|
||||
/**
|
||||
* Poorly named.
|
||||
|
@ -21,7 +22,7 @@ import org.hibernate.internal.util.StringHelper;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NavigableRole implements DotIdentifierSequence {
|
||||
public static final String IDENTIFIER_MAPPER_PROPERTY = "_identifierMapper";
|
||||
public static final String IDENTIFIER_MAPPER_PROPERTY = NavigablePath.IDENTIFIER_MAPPER_PROPERTY;
|
||||
|
||||
private final NavigableRole parent;
|
||||
private final String localName;
|
||||
|
|
|
@ -6,18 +6,22 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.spi;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
||||
/**
|
||||
* Contract for instantiating embeddable values
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface EmbeddableInstantiator extends Instantiator {
|
||||
/**
|
||||
* Create an instance of the embeddable
|
||||
*/
|
||||
Object instantiate(Supplier<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory);
|
||||
|
||||
// default Object instantiate(IntFunction<Object> valueAccess, SessionFactoryImplementor sessionFactory) {
|
||||
// throw new NotYetImplementedFor6Exception( getClass() );
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -39,5 +39,7 @@ public abstract class AbstractFetchParentAccess implements FetchParentAccess {
|
|||
for ( Consumer<Object> listener : listeners ) {
|
||||
listener.accept( parentInstance );
|
||||
}
|
||||
|
||||
listeners.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,19 +6,16 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
|
@ -37,15 +34,20 @@ import org.hibernate.sql.results.internal.NullValueAssembler;
|
|||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
import org.hibernate.type.descriptor.java.spi.EntityJavaTypeDescriptor;
|
||||
|
||||
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentAccess implements EmbeddableInitializer {
|
||||
public static final Object NULL_MARKER = new Object();
|
||||
|
||||
private final NavigablePath navigablePath;
|
||||
private final EmbeddableValuedModelPart embeddedModelPartDescriptor;
|
||||
private final EmbeddableValuedModelPart embedded;
|
||||
private final EmbeddableRepresentationStrategy representationStrategy;
|
||||
private FetchParentAccess fetchParentAccess;
|
||||
|
||||
private final Map<StateArrayContributorMapping, DomainResultAssembler> assemblerMap;
|
||||
private final List<DomainResultAssembler<?>> assemblers;
|
||||
|
||||
// per-row state
|
||||
private final Object[] resolvedValues;
|
||||
|
@ -59,15 +61,25 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
FetchParentAccess fetchParentAccess,
|
||||
AssemblerCreationState creationState) {
|
||||
this.navigablePath = resultDescriptor.getNavigablePath();
|
||||
this.embeddedModelPartDescriptor = resultDescriptor.getReferencedMappingContainer();
|
||||
this.embedded = resultDescriptor.getReferencedMappingContainer();
|
||||
this.fetchParentAccess = fetchParentAccess;
|
||||
|
||||
final EmbeddableMappingType embeddableTypeDescriptor = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor();
|
||||
final EmbeddableMappingType embeddableTypeDescriptor = embedded.getEmbeddableTypeDescriptor();
|
||||
|
||||
if ( embedded instanceof CompositeIdentifierMapping ) {
|
||||
representationStrategy = ( (CompositeIdentifierMapping) embedded )
|
||||
.getMappedIdEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy();
|
||||
}
|
||||
else {
|
||||
representationStrategy = embeddableTypeDescriptor.getRepresentationStrategy();
|
||||
}
|
||||
|
||||
final int numOfAttrs = embeddableTypeDescriptor.getNumberOfAttributeMappings();
|
||||
this.resolvedValues = new Object[ numOfAttrs ];
|
||||
this.assemblerMap = new IdentityHashMap<>( numOfAttrs );
|
||||
this.assemblers = arrayList( numOfAttrs );
|
||||
|
||||
embeddedModelPartDescriptor.visitFetchables(
|
||||
embeddableTypeDescriptor.visitFetchables(
|
||||
stateArrayContributor -> {
|
||||
final Fetch fetch = resultDescriptor.findFetch( stateArrayContributor );
|
||||
|
||||
|
@ -75,7 +87,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
? new NullValueAssembler<>( stateArrayContributor.getJavaTypeDescriptor() )
|
||||
: fetch.createAssembler( this, creationState );
|
||||
|
||||
assemblerMap.put( (StateArrayContributorMapping) stateArrayContributor, stateAssembler );
|
||||
assemblers.add( stateAssembler );
|
||||
},
|
||||
null
|
||||
);
|
||||
|
@ -89,7 +101,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
|
||||
@Override
|
||||
public EmbeddableValuedModelPart getInitializedPart() {
|
||||
return embeddedModelPartDescriptor;
|
||||
return embedded;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
|
@ -103,7 +115,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
|
||||
@Override
|
||||
public Object getCompositeInstance() {
|
||||
return compositeInstance;
|
||||
return compositeInstance == NULL_MARKER ? null : compositeInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -111,9 +123,10 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
if ( compositeInstance != null ) {
|
||||
return;
|
||||
}
|
||||
final PropertyAccess parentInjectionPropertyAccess = embeddedModelPartDescriptor.getParentInjectionAttributePropertyAccess();
|
||||
|
||||
final PropertyAccess parentInjectionPropertyAccess = embedded.getParentInjectionAttributePropertyAccess();
|
||||
final FetchParentAccess fetchParentAccess = getFetchParentAccess();
|
||||
|
||||
if ( parentInjectionPropertyAccess != null && fetchParentAccess != null ) {
|
||||
fetchParentAccess.findFirstEntityDescriptorAccess().registerResolutionListener(
|
||||
// todo (6.0) : this is the legacy behavior
|
||||
|
@ -142,26 +155,20 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
// Special handling for non-aggregated attributes which use the actual entity instance as container,
|
||||
// which we access through the fetch parent access.
|
||||
// If this model part is an identifier, we must construct the instance as this is called during resolveKey
|
||||
final EmbeddableMappingType embeddableTypeDescriptor = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor();
|
||||
final EmbeddableRepresentationStrategy representationStrategy;
|
||||
if ( embeddedModelPartDescriptor instanceof CompositeIdentifierMapping ) {
|
||||
representationStrategy = ( (CompositeIdentifierMapping) embeddedModelPartDescriptor ).getMappedIdEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy();
|
||||
}
|
||||
else {
|
||||
representationStrategy = embeddableTypeDescriptor.getRepresentationStrategy();
|
||||
}
|
||||
final EmbeddableMappingType embeddableTypeDescriptor = embedded.getEmbeddableTypeDescriptor();
|
||||
|
||||
if ( fetchParentAccess != null && embeddableTypeDescriptor.getMappedJavaTypeDescriptor().getJavaTypeClass()
|
||||
.isAssignableFrom( fetchParentAccess.getInitializedPart().getJavaTypeDescriptor().getJavaTypeClass() )
|
||||
&& embeddableTypeDescriptor.getMappedJavaTypeDescriptor() instanceof EntityJavaTypeDescriptor<?>
|
||||
&& !( embeddedModelPartDescriptor instanceof CompositeIdentifierMapping )
|
||||
&& !EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( embeddedModelPartDescriptor.getFetchableName() ) ) {
|
||||
&& !( embedded instanceof CompositeIdentifierMapping )
|
||||
&& !EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( embedded.getFetchableName() ) ) {
|
||||
fetchParentAccess.resolveInstance( rowProcessingState );
|
||||
compositeInstance = fetchParentAccess.getInitializedInstance();
|
||||
}
|
||||
|
||||
if ( compositeInstance == null ) {
|
||||
compositeInstance = representationStrategy.getInstantiator()
|
||||
compositeInstance = representationStrategy
|
||||
.getInstantiator()
|
||||
.instantiate( null, rowProcessingState.getSession().getFactory() );
|
||||
}
|
||||
|
||||
|
@ -173,10 +180,9 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
|
||||
@Override
|
||||
public void initializeInstance(RowProcessingState rowProcessingState) {
|
||||
final PropertyAccess parentInjectionPropertyAccess = embedded.getParentInjectionAttributePropertyAccess();
|
||||
final Initializer initializer = rowProcessingState.resolveInitializer( navigablePath.getParent() );
|
||||
|
||||
final PropertyAccess parentInjectionPropertyAccess = embeddedModelPartDescriptor.getParentInjectionAttributePropertyAccess();
|
||||
|
||||
Initializer initializer = rowProcessingState.resolveInitializer( navigablePath.getParent() );
|
||||
if ( parentInjectionPropertyAccess != null ) {
|
||||
final Object owner;
|
||||
if ( initializer instanceof CollectionInitializer ) {
|
||||
|
@ -207,16 +213,14 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
);
|
||||
|
||||
boolean areAllValuesNull = true;
|
||||
final Set<Map.Entry<StateArrayContributorMapping, DomainResultAssembler>> entries = assemblerMap.entrySet();
|
||||
final int size = entries.size();
|
||||
for ( Map.Entry<StateArrayContributorMapping, DomainResultAssembler> entry : entries ) {
|
||||
final DomainResultAssembler<?> assembler = entry.getValue();
|
||||
for ( int i = 0; i < assemblers.size(); i++ ) {
|
||||
final DomainResultAssembler<?> assembler = assemblers.get( i );
|
||||
final Object contributorValue = assembler.assemble(
|
||||
rowProcessingState,
|
||||
rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions()
|
||||
);
|
||||
|
||||
resolvedValues[entry.getKey().getStateArrayPosition()] = contributorValue;
|
||||
resolvedValues[i] = contributorValue;
|
||||
if ( contributorValue != null ) {
|
||||
areAllValuesNull = false;
|
||||
}
|
||||
|
@ -234,8 +238,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
);
|
||||
}
|
||||
else {
|
||||
Object target = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
Object target = representationStrategy
|
||||
.getInstantiator()
|
||||
.instantiate( null, rowProcessingState.getSession().getFactory() );
|
||||
setPropertyValuesOnTarget( target, rowProcessingState.getSession() );
|
||||
|
@ -258,23 +261,23 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
|
||||
private void setPropertyValuesOnTarget(Object compositeInstance, SharedSessionContractImplementor session) {
|
||||
final EmbeddableMappingType embeddableTypeDescriptor;
|
||||
if ( embeddedModelPartDescriptor instanceof CompositeIdentifierMapping ) {
|
||||
final CompositeIdentifierMapping compositeIdentifierMapping = (CompositeIdentifierMapping) this.embeddedModelPartDescriptor;
|
||||
if ( embedded instanceof CompositeIdentifierMapping ) {
|
||||
final CompositeIdentifierMapping compositeIdentifierMapping = (CompositeIdentifierMapping) embedded;
|
||||
embeddableTypeDescriptor = compositeIdentifierMapping.getMappedIdEmbeddableTypeDescriptor();
|
||||
if ( compositeIdentifierMapping.hasContainingClass() ) {
|
||||
// For id-classes, we might have to transform from the virtual representation to the id-class representation
|
||||
// in case the virtual representation contains a to-one attribute, that is mapped by an embeddable in the id-class
|
||||
embeddedModelPartDescriptor.getEmbeddableTypeDescriptor().forEachAttributeMapping(
|
||||
embedded.getEmbeddableTypeDescriptor().forEachAttributeMapping(
|
||||
(index, attributeMapping) -> {
|
||||
final AttributeMapping idClassAttribute = embeddableTypeDescriptor.getAttributeMappings().get( index );
|
||||
if ( attributeMapping instanceof ToOneAttributeMapping && !( idClassAttribute instanceof ToOneAttributeMapping ) ) {
|
||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
||||
final Object associationKey = toOneAttributeMapping.getForeignKeyDescriptor()
|
||||
.getAssociationKeyFromSide(
|
||||
resolvedValues[index],
|
||||
toOneAttributeMapping.getSideNature().inverse(),
|
||||
session
|
||||
);
|
||||
final ForeignKeyDescriptor fkDescriptor = toOneAttributeMapping.getForeignKeyDescriptor();
|
||||
final Object associationKey = fkDescriptor.getAssociationKeyFromSide(
|
||||
resolvedValues[index],
|
||||
toOneAttributeMapping.getSideNature().inverse(),
|
||||
session
|
||||
);
|
||||
resolvedValues[index] = associationKey;
|
||||
}
|
||||
}
|
||||
|
@ -282,7 +285,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
}
|
||||
}
|
||||
else {
|
||||
embeddableTypeDescriptor = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor();
|
||||
embeddableTypeDescriptor = embedded.getEmbeddableTypeDescriptor();
|
||||
}
|
||||
embeddableTypeDescriptor.setPropertyValues(
|
||||
compositeInstance,
|
||||
|
|
Loading…
Reference in New Issue