Introduce `VirtualIdEmbeddable` and `IdClassEmbeddable`
This initial commit is scaled back - it only introduces the embeddable forms and supporting changes. 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
This commit is contained in:
parent
25d8fda12c
commit
524b46b246
|
@ -15,14 +15,15 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.SelectableMappings;
|
||||
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.SelectableMappings;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
|
@ -62,27 +63,18 @@ public abstract class AbstractCompositeIdentifierMapping
|
|||
private final NavigableRole navigableRole;
|
||||
private final String tableExpression;
|
||||
|
||||
private final StateArrayContributorMetadataAccess attributeMetadataAccess;
|
||||
|
||||
private final EntityMappingType entityMapping;
|
||||
private final EmbeddableMappingType embeddableDescriptor;
|
||||
|
||||
protected final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
public AbstractCompositeIdentifierMapping(
|
||||
StateArrayContributorMetadataAccess attributeMetadataAccess,
|
||||
EmbeddableMappingType embeddableDescriptor,
|
||||
EntityMappingType entityMapping,
|
||||
String tableExpression,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
this.attributeMetadataAccess = attributeMetadataAccess;
|
||||
this.embeddableDescriptor = embeddableDescriptor;
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
this.navigableRole = entityMapping.getNavigableRole().appendContainer( EntityIdentifierMapping.ROLE_LOCAL_NAME );
|
||||
this.entityMapping = entityMapping;
|
||||
this.tableExpression = tableExpression;
|
||||
this.sessionFactory = sessionFactory;
|
||||
|
||||
this.navigableRole = entityMapping.getNavigableRole()
|
||||
.appendContainer( EntityIdentifierMapping.ROLE_LOCAL_NAME );
|
||||
this.sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,28 +83,18 @@ public abstract class AbstractCompositeIdentifierMapping
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getMappedIdEmbeddableTypeDescriptor() {
|
||||
return embeddableDescriptor;
|
||||
public IEmbeddableMappingType getMappedType() {
|
||||
return getPartMappingType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getMappedType() {
|
||||
return embeddableDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getPartMappingType() {
|
||||
return getEmbeddableTypeDescriptor();
|
||||
public IEmbeddableMappingType getEmbeddableTypeDescriptor() {
|
||||
return getPartMappingType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType<?> getJavaTypeDescriptor() {
|
||||
return getEmbeddableTypeDescriptor().getMappedJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getEmbeddableTypeDescriptor() {
|
||||
return embeddableDescriptor;
|
||||
return getPartMappingType().getMappedJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -188,14 +170,14 @@ public abstract class AbstractCompositeIdentifierMapping
|
|||
|
||||
@Override
|
||||
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||
return embeddableDescriptor.findSubPart( name, treatTargetType );
|
||||
return getPartMappingType().findSubPart( name, treatTargetType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSubParts(
|
||||
Consumer<ModelPart> consumer,
|
||||
EntityMappingType treatTargetType) {
|
||||
embeddableDescriptor.visitSubParts( consumer, treatTargetType );
|
||||
getPartMappingType().visitSubParts( consumer, treatTargetType );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.function.Supplier;
|
|||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
|
||||
/**
|
||||
|
@ -22,11 +22,11 @@ import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
|||
public class EmbeddableInstantiatorDynamicMap
|
||||
extends AbstractDynamicMapInstantiator
|
||||
implements EmbeddableInstantiator {
|
||||
private final Supplier<EmbeddableMappingType> runtimeDescriptorAccess;
|
||||
private final Supplier<IEmbeddableMappingType> runtimeDescriptorAccess;
|
||||
|
||||
public EmbeddableInstantiatorDynamicMap(
|
||||
Component bootDescriptor,
|
||||
Supplier<EmbeddableMappingType> runtimeDescriptorAccess) {
|
||||
Supplier<IEmbeddableMappingType> runtimeDescriptorAccess) {
|
||||
super( bootDescriptor.getRoleName() );
|
||||
this.runtimeDescriptorAccess = runtimeDescriptorAccess;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public class EmbeddableInstantiatorDynamicMap
|
|||
final Map<?,?> dataMap = generateDataMap();
|
||||
|
||||
if ( valuesAccess != null ) {
|
||||
final EmbeddableMappingType mappingType = runtimeDescriptorAccess.get();
|
||||
final IEmbeddableMappingType mappingType = runtimeDescriptorAccess.get();
|
||||
mappingType.setPropertyValues( dataMap, valuesAccess.get() );
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
|
@ -28,11 +28,11 @@ import org.hibernate.type.descriptor.java.JavaType;
|
|||
public class EmbeddableInstantiatorPojoStandard extends AbstractPojoInstantiator implements EmbeddableInstantiator {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoInstantiatorImpl.class );
|
||||
|
||||
private final Supplier<EmbeddableMappingType> embeddableMappingAccess;
|
||||
private final Supplier<IEmbeddableMappingType> embeddableMappingAccess;
|
||||
private final Constructor<?> constructor;
|
||||
|
||||
public EmbeddableInstantiatorPojoStandard(
|
||||
Supplier<EmbeddableMappingType> embeddableMappingAccess,
|
||||
Supplier<IEmbeddableMappingType> embeddableMappingAccess,
|
||||
JavaType<?> javaTypeDescriptor) {
|
||||
super( javaTypeDescriptor.getJavaTypeClass() );
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
|||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
|
@ -30,7 +30,7 @@ public class EmbeddableRepresentationStrategyMap implements EmbeddableRepresenta
|
|||
|
||||
public EmbeddableRepresentationStrategyMap(
|
||||
Component bootDescriptor,
|
||||
Supplier<EmbeddableMappingType> runtimeDescriptorAccess,
|
||||
Supplier<IEmbeddableMappingType> runtimeDescriptorAccess,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
this.mapJtd = creationContext.getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Map.class );
|
||||
this.instantiator = new EmbeddableInstantiatorDynamicMap( bootDescriptor, runtimeDescriptorAccess );
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.hibernate.mapping.Component;
|
|||
import org.hibernate.mapping.IndexBackref;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||
|
@ -41,7 +41,7 @@ public class EmbeddableRepresentationStrategyPojo extends AbstractEmbeddableRepr
|
|||
|
||||
public EmbeddableRepresentationStrategyPojo(
|
||||
Component bootDescriptor,
|
||||
Supplier<EmbeddableMappingType> runtimeDescriptorAccess,
|
||||
Supplier<IEmbeddableMappingType> runtimeDescriptorAccess,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
super(
|
||||
bootDescriptor,
|
||||
|
@ -70,7 +70,7 @@ public class EmbeddableRepresentationStrategyPojo extends AbstractEmbeddableRepr
|
|||
this.instantiator = determineInstantiator( runtimeDescriptorAccess );
|
||||
}
|
||||
|
||||
private EmbeddableInstantiator determineInstantiator(Supplier<EmbeddableMappingType> runtimeDescriptorAccess) {
|
||||
private EmbeddableInstantiator determineInstantiator(Supplier<IEmbeddableMappingType> runtimeDescriptorAccess) {
|
||||
if ( reflectionOptimizer != null && reflectionOptimizer.getInstantiationOptimizer() != null ) {
|
||||
final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer();
|
||||
return new EmbeddableInstantiatorPojoOptimized(
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.function.Supplier;
|
|||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
||||
|
@ -61,7 +61,7 @@ public class ManagedTypeRepresentationResolverStandard implements ManagedTypeRep
|
|||
@Override
|
||||
public EmbeddableRepresentationStrategy resolveStrategy(
|
||||
Component bootDescriptor,
|
||||
Supplier<EmbeddableMappingType> runtimeDescriptorAccess,
|
||||
Supplier<IEmbeddableMappingType> runtimeDescriptorAccess,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
// RepresentationMode representation = bootDescriptor.getExplicitRepresentationMode();
|
||||
RepresentationMode representation = null;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
import org.hibernate.tuple.ValueGeneration;
|
||||
|
@ -34,6 +35,17 @@ public interface AttributeMapping extends ModelPart, ValueMapping, Fetchable, Pr
|
|||
*/
|
||||
PropertyAccess getPropertyAccess();
|
||||
|
||||
/**
|
||||
* Convenient access to getting the value for this attribute from the "owner"
|
||||
*/
|
||||
default Object getValue(Object container, SharedSessionContractImplementor session) {
|
||||
return getPropertyAccess().getGetter().get( container );
|
||||
}
|
||||
|
||||
default void setValue(Object container, Object value, SharedSessionContractImplementor session) {
|
||||
getPropertyAccess().getSetter().set( container, value, session.getSessionFactory() );
|
||||
}
|
||||
|
||||
/**
|
||||
* The value generation strategy to use for this attribute.
|
||||
*
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.IdentifierValue;
|
||||
|
||||
/**
|
||||
|
@ -30,11 +28,11 @@ public interface CompositeIdentifierMapping extends EntityIdentifierMapping {
|
|||
*/
|
||||
boolean hasContainingClass();
|
||||
|
||||
EmbeddableMappingType getPartMappingType();
|
||||
IEmbeddableMappingType getPartMappingType();
|
||||
|
||||
/**
|
||||
* Returns the embeddable type descriptor of the id-class, if there is one,
|
||||
* otherwise the one of the virtual embeddable mapping type.
|
||||
*/
|
||||
EmbeddableMappingType getMappedIdEmbeddableTypeDescriptor();
|
||||
IEmbeddableMappingType getMappedIdEmbeddableTypeDescriptor();
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EmbeddableMappingType implements ManagedMappingType, SelectableMappings {
|
||||
public class EmbeddableMappingType implements IEmbeddableMappingType {
|
||||
|
||||
public static EmbeddableMappingType from(
|
||||
Component bootDescriptor,
|
||||
|
@ -176,15 +176,15 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
|||
|
||||
}
|
||||
|
||||
private EmbeddableMappingType(
|
||||
public EmbeddableMappingType(
|
||||
EmbeddedAttributeMapping valueMapping,
|
||||
TableGroupProducer declaringTableGroupProducer,
|
||||
SelectableMappings selectableMappings,
|
||||
EmbeddableMappingType inverseMappingType,
|
||||
IEmbeddableMappingType inverseMappingType,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
this.embeddableJtd = inverseMappingType.embeddableJtd;
|
||||
this.representationStrategy = inverseMappingType.representationStrategy;
|
||||
this.sessionFactory = inverseMappingType.sessionFactory;
|
||||
this.embeddableJtd = inverseMappingType.getJavaTypeDescriptor();
|
||||
this.representationStrategy = inverseMappingType.getRepresentationStrategy();
|
||||
this.sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
this.valueMapping = valueMapping;
|
||||
this.createEmptyCompositesEnabled = inverseMappingType.isCreateEmptyCompositesEnabled();
|
||||
this.selectableMappings = selectableMappings;
|
||||
|
@ -192,14 +192,14 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
|||
creationProcess.registerInitializationCallback(
|
||||
"EmbeddableMappingType(" + inverseMappingType.getNavigableRole().getFullPath() + ".{inverse})#finishInitialization",
|
||||
() -> {
|
||||
if ( inverseMappingType.attributeMappings.isEmpty() ) {
|
||||
if ( inverseMappingType.getAttributeMappings().isEmpty() ) {
|
||||
return false;
|
||||
}
|
||||
// Reset the attribute mappings that were added in previous attempts
|
||||
this.attributeMappings.clear();
|
||||
int currentIndex = 0;
|
||||
// We copy the attributes from the inverse mappings and replace the selection mappings
|
||||
for ( AttributeMapping attributeMapping : inverseMappingType.attributeMappings ) {
|
||||
for ( AttributeMapping attributeMapping : inverseMappingType.getAttributeMappings() ) {
|
||||
if ( attributeMapping instanceof BasicAttributeMapping ) {
|
||||
final BasicAttributeMapping original = (BasicAttributeMapping) attributeMapping;
|
||||
final SelectableMapping selectableMapping = selectableMappings.getSelectable( currentIndex );
|
||||
|
@ -249,6 +249,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType createInverseMappingType(
|
||||
EmbeddedAttributeMapping valueMapping,
|
||||
TableGroupProducer declaringTableGroupProducer,
|
||||
|
@ -547,6 +548,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
|||
attributeMappings.add( attributeMapping );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableValuedModelPart getEmbeddedValueMapping() {
|
||||
return valueMapping;
|
||||
}
|
||||
|
@ -556,6 +558,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
|||
return embeddableJtd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableRepresentationStrategy getRepresentationStrategy() {
|
||||
return representationStrategy;
|
||||
}
|
||||
|
@ -778,6 +781,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
|||
visitAttributeMappings( consumer::accept );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getPropertyValues(Object compositeInstance) {
|
||||
final Object[] results = new Object[attributeMappings.size()];
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
|
@ -791,6 +795,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
|||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyValues(Object compositeInstance, Object[] resolvedValues) {
|
||||
// todo (6.0) : reflection optimizer...
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
|
@ -803,6 +808,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreateEmptyCompositesEnabled() {
|
||||
return createEmptyCompositesEnabled;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,7 @@ import org.hibernate.sql.results.graph.FetchableContainer;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface EmbeddableValuedModelPart extends ModelPart, Fetchable, FetchableContainer, TableGroupJoinProducer {
|
||||
|
||||
EmbeddableMappingType getEmbeddableTypeDescriptor();
|
||||
IEmbeddableMappingType getEmbeddableTypeDescriptor();
|
||||
|
||||
@Override
|
||||
default int getJdbcTypeCount() {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.mapping.IndexedConsumer;
|
||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface IEmbeddableMappingType extends ManagedMappingType, SelectableMappings {
|
||||
IEmbeddableMappingType createInverseMappingType(
|
||||
EmbeddedAttributeMapping valueMapping,
|
||||
TableGroupProducer declaringTableGroupProducer,
|
||||
SelectableMappings selectableMappings,
|
||||
MappingModelCreationProcess creationProcess);
|
||||
|
||||
EmbeddableValuedModelPart getEmbeddedValueMapping();
|
||||
|
||||
EmbeddableRepresentationStrategy getRepresentationStrategy();
|
||||
|
||||
Object[] getPropertyValues(Object compositeInstance);
|
||||
|
||||
void setPropertyValues(Object compositeInstance, Object[] resolvedValues);
|
||||
|
||||
boolean isCreateEmptyCompositesEnabled();
|
||||
|
||||
@Override
|
||||
default int forEachSelectable(SelectableConsumer consumer) {
|
||||
return ManagedMappingType.super.forEachSelectable( consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
int forEachSelectable(int offset, SelectableConsumer consumer);
|
||||
|
||||
@Override
|
||||
int getJdbcTypeCount();
|
||||
|
||||
@Override
|
||||
List<JdbcMapping> getJdbcMappings();
|
||||
|
||||
@Override
|
||||
int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action);
|
||||
}
|
|
@ -16,9 +16,9 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
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.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
|
@ -66,7 +66,7 @@ public class EmbeddedAttributeMapping
|
|||
private final NavigableRole navigableRole;
|
||||
|
||||
private final String tableExpression;
|
||||
private final EmbeddableMappingType embeddableMappingType;
|
||||
private final IEmbeddableMappingType embeddableMappingType;
|
||||
private final PropertyAccess parentInjectionAttributePropertyAccess;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
|
@ -79,7 +79,7 @@ public class EmbeddedAttributeMapping
|
|||
String parentInjectionAttributeName,
|
||||
FetchTiming mappedFetchTiming,
|
||||
FetchStyle mappedFetchStyle,
|
||||
EmbeddableMappingType embeddableMappingType,
|
||||
IEmbeddableMappingType embeddableMappingType,
|
||||
ManagedMappingType declaringType,
|
||||
PropertyAccess propertyAccess,
|
||||
ValueGeneration valueGeneration) {
|
||||
|
@ -89,7 +89,7 @@ public class EmbeddedAttributeMapping
|
|||
stateArrayPosition,
|
||||
tableExpression,
|
||||
attributeMetadataAccess,
|
||||
getPropertyAccess(parentInjectionAttributeName, embeddableMappingType),
|
||||
getPropertyAccess(parentInjectionAttributeName, embeddableMappingType),
|
||||
mappedFetchTiming,
|
||||
mappedFetchStyle,
|
||||
embeddableMappingType,
|
||||
|
@ -108,7 +108,7 @@ public class EmbeddedAttributeMapping
|
|||
PropertyAccess parentInjectionAttributePropertyAccess,
|
||||
FetchTiming mappedFetchTiming,
|
||||
FetchStyle mappedFetchStyle,
|
||||
EmbeddableMappingType embeddableMappingType,
|
||||
IEmbeddableMappingType embeddableMappingType,
|
||||
ManagedMappingType declaringType,
|
||||
PropertyAccess propertyAccess,
|
||||
ValueGeneration valueGeneration) {
|
||||
|
@ -137,7 +137,7 @@ public class EmbeddedAttributeMapping
|
|||
TableGroupProducer declaringTableGroupProducer,
|
||||
SelectableMappings selectableMappings,
|
||||
EmbeddableValuedModelPart inverseModelPart,
|
||||
EmbeddableMappingType embeddableTypeDescriptor,
|
||||
IEmbeddableMappingType embeddableTypeDescriptor,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
super(
|
||||
inverseModelPart.getFetchableName(),
|
||||
|
@ -167,7 +167,7 @@ public class EmbeddedAttributeMapping
|
|||
TableGroupProducer declaringTableGroupProducer,
|
||||
SelectableMappings selectableMappings,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
final EmbeddableMappingType embeddableTypeDescriptor;
|
||||
final IEmbeddableMappingType embeddableTypeDescriptor;
|
||||
if ( modelPart instanceof CompositeIdentifierMapping ) {
|
||||
embeddableTypeDescriptor = ( (CompositeIdentifierMapping) modelPart ).getMappedIdEmbeddableTypeDescriptor();
|
||||
}
|
||||
|
@ -185,12 +185,12 @@ public class EmbeddedAttributeMapping
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getMappedType() {
|
||||
public IEmbeddableMappingType getMappedType() {
|
||||
return getEmbeddableTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getEmbeddableTypeDescriptor() {
|
||||
public IEmbeddableMappingType getEmbeddableTypeDescriptor() {
|
||||
return embeddableMappingType;
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ public class EmbeddedAttributeMapping
|
|||
|
||||
private static PropertyAccess getPropertyAccess(
|
||||
String parentInjectionAttributeName,
|
||||
EmbeddableMappingType embeddableMappingType) {
|
||||
IEmbeddableMappingType embeddableMappingType) {
|
||||
final PropertyAccess parentInjectionAttributePropertyAccess;
|
||||
if ( parentInjectionAttributeName != null ) {
|
||||
parentInjectionAttributePropertyAccess = PropertyAccessStrategyBasicImpl.INSTANCE.buildPropertyAccess(
|
||||
|
|
|
@ -15,8 +15,8 @@ import org.hibernate.engine.FetchStyle;
|
|||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
|
@ -61,7 +61,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
|||
private final NavigableRole navigableRole;
|
||||
private final CollectionPersister collectionDescriptor;
|
||||
private final Nature nature;
|
||||
private final EmbeddableMappingType embeddableMappingType;
|
||||
private final IEmbeddableMappingType embeddableMappingType;
|
||||
|
||||
private final String containingTableExpression;
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
|||
public EmbeddedCollectionPart(
|
||||
CollectionPersister collectionDescriptor,
|
||||
Nature nature,
|
||||
EmbeddableMappingType embeddableMappingType,
|
||||
IEmbeddableMappingType embeddableMappingType,
|
||||
String parentInjectionAttributeName,
|
||||
String containingTableExpression,
|
||||
String sqlAliasStem) {
|
||||
|
@ -116,7 +116,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getEmbeddableTypeDescriptor() {
|
||||
public IEmbeddableMappingType getEmbeddableTypeDescriptor() {
|
||||
return embeddableMappingType;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,13 +8,11 @@ package org.hibernate.metamodel.mapping.internal;
|
|||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.internal.AbstractCompositeIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
|
@ -32,26 +30,21 @@ public class EmbeddedIdentifierMappingImpl
|
|||
extends AbstractCompositeIdentifierMapping
|
||||
implements SingleAttributeIdentifierMapping {
|
||||
private final String name;
|
||||
private final IEmbeddableMappingType embeddableDescriptor;
|
||||
private final PropertyAccess propertyAccess;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public EmbeddedIdentifierMappingImpl(
|
||||
EntityMappingType entityMapping,
|
||||
String name,
|
||||
EmbeddableMappingType embeddableDescriptor,
|
||||
StateArrayContributorMetadataAccess attributeMetadataAccess,
|
||||
IEmbeddableMappingType embeddableDescriptor,
|
||||
PropertyAccess propertyAccess,
|
||||
String tableExpression,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
super(
|
||||
attributeMetadataAccess,
|
||||
embeddableDescriptor,
|
||||
entityMapping,
|
||||
tableExpression,
|
||||
sessionFactory
|
||||
);
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
super( entityMapping, tableExpression, creationProcess );
|
||||
|
||||
this.name = name;
|
||||
this.embeddableDescriptor = embeddableDescriptor;
|
||||
this.propertyAccess = propertyAccess;
|
||||
}
|
||||
|
||||
|
@ -60,6 +53,16 @@ public class EmbeddedIdentifierMappingImpl
|
|||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEmbeddableMappingType getPartMappingType() {
|
||||
return embeddableDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEmbeddableMappingType getMappedIdEmbeddableTypeDescriptor() {
|
||||
return getMappedType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySqlSelections(
|
||||
NavigablePath navigablePath, TableGroup tableGroup, DomainResultCreationState creationState) {
|
||||
|
@ -139,7 +142,7 @@ public class EmbeddedIdentifierMappingImpl
|
|||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
final EmbeddableMappingType embeddableTypeDescriptor = getEmbeddableTypeDescriptor();
|
||||
final IEmbeddableMappingType embeddableTypeDescriptor = getEmbeddableTypeDescriptor();
|
||||
final Object[] result = new Object[embeddableTypeDescriptor.getNumberOfAttributeMappings()];
|
||||
embeddableTypeDescriptor.forEachAttributeMapping(
|
||||
(i, mapping) -> {
|
||||
|
|
|
@ -0,0 +1,780 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.SharedSessionContract;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.Any;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.IndexedConsumer;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.RootClass;
|
||||
import org.hibernate.mapping.Selectable;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingModelCreationLogger;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
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.internal.NonAggregatedIdentifierMapping.IdentifierValueMapper;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.type.AnyType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||
import org.hibernate.type.spi.CompositeTypeImplementor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
|
||||
import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.getStateArrayContributorMetadataAccess;
|
||||
|
||||
/**
|
||||
* EmbeddableMappingType implementation describing an
|
||||
* {@link jakarta.persistence.IdClass}
|
||||
*/
|
||||
public class IdClassEmbeddable implements IdentifierValueMapper {
|
||||
private final NavigableRole navigableRole;
|
||||
private final NonAggregatedIdentifierMapping idMapping;
|
||||
private final VirtualIdEmbeddable virtualIdEmbeddable;
|
||||
private final JavaType<?> javaType;
|
||||
private final IdClassRepresentationStrategy representationStrategy;
|
||||
// private final IdClassEmbedded embedded;
|
||||
private final EmbeddableValuedModelPart embedded;
|
||||
|
||||
private final List<SingularAttributeMapping> attributeMappings;
|
||||
private SelectableMappings selectableMappings;
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
public IdClassEmbeddable(
|
||||
Component idClassSource,
|
||||
RootClass bootEntityDescriptor,
|
||||
NonAggregatedIdentifierMapping idMapping,
|
||||
EntityMappingType identifiedEntityMapping,
|
||||
String idTable,
|
||||
String[] idColumns,
|
||||
VirtualIdEmbeddable virtualIdEmbeddable,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
this.sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
|
||||
this.navigableRole = idMapping.getNavigableRole().append( NavigablePath.IDENTIFIER_MAPPER_PROPERTY );
|
||||
this.idMapping = idMapping;
|
||||
this.virtualIdEmbeddable = virtualIdEmbeddable;
|
||||
|
||||
this.javaType = sessionFactory.getTypeConfiguration()
|
||||
.getJavaTypeDescriptorRegistry()
|
||||
.resolveManagedTypeDescriptor( idClassSource.getComponentClass() );
|
||||
|
||||
this.representationStrategy = new IdClassRepresentationStrategy( this );
|
||||
|
||||
this.attributeMappings = arrayList( idClassSource.getPropertySpan() );
|
||||
|
||||
final PropertyAccess propertyAccess = PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess(
|
||||
null,
|
||||
EntityIdentifierMapping.ROLE_LOCAL_NAME
|
||||
);
|
||||
final StateArrayContributorMetadataAccess attributeMetadataAccess = getStateArrayContributorMetadataAccess(
|
||||
propertyAccess
|
||||
);
|
||||
|
||||
embedded = new EmbeddedAttributeMapping(
|
||||
NavigablePath.IDENTIFIER_MAPPER_PROPERTY,
|
||||
identifiedEntityMapping.getNavigableRole()
|
||||
.append( EntityIdentifierMapping.ROLE_LOCAL_NAME )
|
||||
.append( NavigablePath.IDENTIFIER_MAPPER_PROPERTY ),
|
||||
-1,
|
||||
idTable,
|
||||
attributeMetadataAccess,
|
||||
(PropertyAccess) null,
|
||||
FetchTiming.IMMEDIATE,
|
||||
FetchStyle.JOIN,
|
||||
this,
|
||||
identifiedEntityMapping,
|
||||
propertyAccess,
|
||||
null
|
||||
);
|
||||
|
||||
final CompositeType idClassType = (CompositeType) idClassSource.getType();
|
||||
( (CompositeTypeImplementor) idClassType ).injectMappingModelPart( embedded, creationProcess );
|
||||
|
||||
creationProcess.registerInitializationCallback(
|
||||
"IdClassEmbeddable(" + navigableRole.getFullPath() + ")#finishInitialization",
|
||||
() -> {
|
||||
try {
|
||||
final boolean finished = finishInitialization(
|
||||
idClassSource,
|
||||
idClassType,
|
||||
idTable,
|
||||
idColumns,
|
||||
creationProcess
|
||||
);
|
||||
|
||||
if ( finished ) {
|
||||
return finished;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
MappingModelCreationLogger.LOGGER.debugf(
|
||||
e,
|
||||
"(DEBUG) Error finalizing IdClassEmbeddable(%s)",
|
||||
navigableRole
|
||||
);
|
||||
}
|
||||
|
||||
MappingModelCreationLogger.LOGGER.debugf(
|
||||
"IdClassEmbeddable(%s) finalization was not able to complete successfully",
|
||||
navigableRole
|
||||
);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// IdentifierValueMapper
|
||||
|
||||
@Override
|
||||
public EmbeddableValuedModelPart getEmbeddedPart() {
|
||||
return embedded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
|
||||
final Object id = representationStrategy.getInstantiator().instantiate(
|
||||
null,
|
||||
sessionFactory
|
||||
);
|
||||
|
||||
final List<AttributeMapping> virtualIdAttribute = virtualIdEmbeddable.getAttributeMappings();
|
||||
final List<AttributeMapping> idClassAttribute = getAttributeMappings();
|
||||
final Object[] propertyValues = new Object[virtualIdAttribute.size()];
|
||||
|
||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||
final AttributeMapping attributeMapping = virtualIdAttribute.get( i );
|
||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
||||
if ( o == null ) {
|
||||
final AttributeMapping idClassAttributeMapping = idClassAttribute.get( i );
|
||||
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
||||
propertyValues[i] = idClassAttributeMapping.getExpressableJavaTypeDescriptor().getDefaultValue();
|
||||
}
|
||||
else {
|
||||
propertyValues[i] = null;
|
||||
}
|
||||
}
|
||||
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
||||
else if ( attributeMapping instanceof ToOneAttributeMapping
|
||||
&& !( idClassAttribute.get( i ) instanceof ToOneAttributeMapping ) ) {
|
||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
||||
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
|
||||
toOneAttributeMapping.getSideNature().inverse()
|
||||
);
|
||||
if ( targetPart instanceof EntityIdentifierMapping ) {
|
||||
propertyValues[i] = ( (EntityIdentifierMapping) targetPart ).getIdentifier( o, session );
|
||||
}
|
||||
else {
|
||||
propertyValues[i] = o;
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
propertyValues[i] = o;
|
||||
}
|
||||
}
|
||||
|
||||
setPropertyValues( id, propertyValues );
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
|
||||
final Object[] propertyValues = new Object[attributeMappings.size()];
|
||||
virtualIdEmbeddable.forEachAttribute(
|
||||
(position, virtualIdAttribute) -> {
|
||||
final AttributeMapping idClassAttribute = attributeMappings.get( position );
|
||||
final Object o = idClassAttribute.getPropertyAccess().getGetter().get( id );
|
||||
if ( virtualIdAttribute instanceof ToOneAttributeMapping && !( idClassAttribute instanceof ToOneAttributeMapping ) ) {
|
||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) virtualIdAttribute;
|
||||
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType()
|
||||
.getEntityPersister();
|
||||
final EntityKey entityKey = session.generateEntityKey( o, entityPersister );
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
// it is conceivable there is a proxy, so check that first
|
||||
propertyValues[position] = persistenceContext.getProxy( entityKey );
|
||||
if ( propertyValues[position] == null ) {
|
||||
// otherwise look for an initialized version
|
||||
propertyValues[position] = persistenceContext.getEntity( entityKey );
|
||||
if ( propertyValues[position] == null ) {
|
||||
// get the association out of the entity itself
|
||||
propertyValues[position] = factory.getMetamodel()
|
||||
.findEntityDescriptor( entity.getClass() )
|
||||
.getPropertyValue( entity, toOneAttributeMapping.getAttributeName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
propertyValues[position] = o;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
virtualIdEmbeddable.setPropertyValues( entity, propertyValues );
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// EmbeddableMappingType
|
||||
|
||||
@Override
|
||||
public NavigableRole getNavigableRole() {
|
||||
return navigableRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPartName() {
|
||||
return NavigablePath.IDENTIFIER_MAPPER_PROPERTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableRepresentationStrategy getRepresentationStrategy() {
|
||||
return representationStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType<?> getMappedJavaTypeDescriptor() {
|
||||
return javaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableValuedModelPart getEmbeddedValueMapping() {
|
||||
return embedded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfAttributeMappings() {
|
||||
return attributeMappings.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreateEmptyCompositesEnabled() {
|
||||
// generally we do not want empty composites for identifiers
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingularAttributeMapping findAttributeMapping(String name) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final SingularAttributeMapping attribute = attributeMappings.get( i );
|
||||
if ( attribute.getAttributeName().equals( name ) ) {
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public List<AttributeMapping> getAttributeMappings() {
|
||||
return (List) attributeMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAttributeMappings(Consumer<? super AttributeMapping> action) {
|
||||
forEachAttribute( (index, attribute) -> action.accept( attribute ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachAttributeMapping(IndexedConsumer<AttributeMapping> consumer) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
consumer.accept( i, attributeMappings.get( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getPropertyValues(Object composite) {
|
||||
final Object[] values = new Object[ attributeMappings.size() ];
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final SingularAttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
values[i] = attributeMapping.getPropertyAccess().getGetter().get( composite );
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyValues(Object composite, Object[] resolvedValues) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final SingularAttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
attributeMapping.getPropertyAccess().getSetter().set( composite, resolvedValues[i], sessionFactory );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfFetchables() {
|
||||
return getNumberOfAttributeMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType findContainingEntityMapping() {
|
||||
return idMapping.findContainingEntityMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSubParts(Consumer<ModelPart> consumer, EntityMappingType treatTargetType) {
|
||||
attributeMappings.forEach( consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final SingularAttributeMapping attribute = attributeMappings.get( i );
|
||||
if ( attribute.getAttributeName().equals( name ) ) {
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
||||
attributeMappings.forEach( (attribute) -> {
|
||||
final Object attributeValue = attribute.getValue( domainValue, session );
|
||||
attribute.breakDownJdbcValues( attributeValue, valueConsumer, session );
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectableMapping getSelectable(int columnIndex) {
|
||||
return selectableMappings.getSelectable( columnIndex );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(SelectableConsumer consumer) {
|
||||
return selectableMappings.forEachSelectable( 0, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(int offset, SelectableConsumer consumer) {
|
||||
return selectableMappings.forEachSelectable( offset, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJdbcTypeCount() {
|
||||
return selectableMappings.getJdbcTypeCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JdbcMapping> getJdbcMappings() {
|
||||
return selectableMappings.getJdbcMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcValue(
|
||||
Object value,
|
||||
Clause clause,
|
||||
int offset,
|
||||
JdbcValuesConsumer valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
int span = 0;
|
||||
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
if ( attributeMapping instanceof PluralAttributeMapping ) {
|
||||
continue;
|
||||
}
|
||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
span += attributeMapping.forEachJdbcValue( o, clause, span + offset, valuesConsumer, session );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
final List<AttributeMapping> attributeMappings = getAttributeMappings();
|
||||
|
||||
// todo (6.0) : reduce to-one values to id here?
|
||||
final Object[] result = new Object[ attributeMappings.size() ];
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
result[i] = attributeMapping.disassemble( o, session );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
||||
return selectableMappings.forEachSelectable(
|
||||
offset,
|
||||
(index, selectable) -> action.accept( index, selectable.getJdbcMapping() )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(NavigablePath navigablePath, TableGroup tableGroup, String resultVariable, DomainResultCreationState creationState) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEmbeddableMappingType createInverseMappingType(
|
||||
EmbeddedAttributeMapping valueMapping,
|
||||
TableGroupProducer declaringTableGroupProducer,
|
||||
SelectableMappings selectableMappings,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
return new EmbeddableMappingType(
|
||||
valueMapping,
|
||||
declaringTableGroupProducer,
|
||||
selectableMappings,
|
||||
this,
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// init
|
||||
|
||||
private boolean finishInitialization(
|
||||
Component bootDescriptor,
|
||||
CompositeType compositeType,
|
||||
String rootTableExpression,
|
||||
String[] rootTableKeyColumnNames,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
final SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
||||
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
|
||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||
final Dialect dialect = jdbcEnvironment.getDialect();
|
||||
|
||||
final Type[] subtypes = compositeType.getSubtypes();
|
||||
|
||||
int attributeIndex = 0;
|
||||
int columnPosition = 0;
|
||||
|
||||
// Reset the attribute mappings that were added in previous attempts
|
||||
this.attributeMappings.clear();
|
||||
|
||||
final Iterator<Property> propertyIterator = bootDescriptor.getPropertyIterator();
|
||||
while ( propertyIterator.hasNext() ) {
|
||||
final Property bootPropertyDescriptor = propertyIterator.next();
|
||||
|
||||
final PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess( bootPropertyDescriptor );
|
||||
|
||||
final AttributeMapping attributeMapping;
|
||||
|
||||
final Type subtype = subtypes[ attributeIndex ];
|
||||
if ( subtype instanceof BasicType ) {
|
||||
final BasicValue basicValue = (BasicValue) bootPropertyDescriptor.getValue();
|
||||
final Selectable selectable = basicValue.getColumn();
|
||||
final String containingTableExpression;
|
||||
final String columnExpression;
|
||||
if ( rootTableKeyColumnNames == null ) {
|
||||
if ( selectable.isFormula() ) {
|
||||
columnExpression = selectable.getTemplate( dialect, creationProcess.getSqmFunctionRegistry() );
|
||||
}
|
||||
else {
|
||||
columnExpression = selectable.getText( dialect );
|
||||
}
|
||||
if ( selectable instanceof Column ) {
|
||||
containingTableExpression = getTableIdentifierExpression(
|
||||
( (Column) selectable ).getValue().getTable(),
|
||||
jdbcEnvironment
|
||||
);
|
||||
}
|
||||
else {
|
||||
containingTableExpression = rootTableExpression;
|
||||
}
|
||||
}
|
||||
else {
|
||||
containingTableExpression = rootTableExpression;
|
||||
columnExpression = rootTableKeyColumnNames[ columnPosition ];
|
||||
}
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
navigableRole.append( bootPropertyDescriptor.getName() ),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
this,
|
||||
(BasicType<?>) subtype,
|
||||
containingTableExpression,
|
||||
columnExpression,
|
||||
selectable.isFormula(),
|
||||
selectable.getCustomReadExpression(),
|
||||
selectable.getCustomWriteExpression(),
|
||||
propertyAccess,
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
creationProcess
|
||||
);
|
||||
|
||||
columnPosition++;
|
||||
}
|
||||
else if ( subtype instanceof AnyType ) {
|
||||
final Any bootValueMapping = (Any) bootPropertyDescriptor.getValue();
|
||||
final AnyType anyType = (AnyType) subtype;
|
||||
|
||||
final boolean nullable = bootValueMapping.isNullable();
|
||||
final boolean insertable = bootPropertyDescriptor.isInsertable();
|
||||
final boolean updateable = bootPropertyDescriptor.isUpdateable();
|
||||
final boolean includeInOptimisticLocking = bootPropertyDescriptor.isOptimisticLocked();
|
||||
final CascadeStyle cascadeStyle = compositeType.getCascadeStyle( attributeIndex );
|
||||
final MutabilityPlan<?> mutabilityPlan;
|
||||
|
||||
if ( updateable ) {
|
||||
mutabilityPlan = new MutabilityPlan<Object>() {
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object deepCopy(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return anyType.deepCopy( value, creationProcess.getCreationContext().getSessionFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SharedSessionContract session) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(Serializable cached, SharedSessionContract session) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
mutabilityPlan = ImmutableMutabilityPlan.INSTANCE;
|
||||
}
|
||||
|
||||
final StateArrayContributorMetadataAccess attributeMetadataAccess = entityMappingType -> new StateArrayContributorMetadata() {
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutabilityPlan<?> getMutabilityPlan() {
|
||||
return mutabilityPlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertable() {
|
||||
return insertable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return updateable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInDirtyChecking() {
|
||||
// todo (6.0) : do not believe this is correct
|
||||
return updateable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInOptimisticLocking() {
|
||||
return includeInOptimisticLocking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CascadeStyle getCascadeStyle() {
|
||||
return cascadeStyle;
|
||||
}
|
||||
};
|
||||
|
||||
attributeMapping = new DiscriminatedAssociationAttributeMapping(
|
||||
navigableRole.append( bootPropertyDescriptor.getName() ),
|
||||
typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Object.class ),
|
||||
this,
|
||||
attributeIndex,
|
||||
attributeMetadataAccess,
|
||||
bootPropertyDescriptor.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE,
|
||||
propertyAccess,
|
||||
bootPropertyDescriptor,
|
||||
anyType,
|
||||
bootValueMapping,
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
else if ( subtype instanceof CompositeType ) {
|
||||
final CompositeType subCompositeType = (CompositeType) subtype;
|
||||
final int columnSpan = subCompositeType.getColumnSpan( sessionFactory );
|
||||
final String subTableExpression;
|
||||
final String[] subRootTableKeyColumnNames;
|
||||
if ( rootTableKeyColumnNames == null ) {
|
||||
subTableExpression = rootTableExpression;
|
||||
subRootTableKeyColumnNames = null;
|
||||
}
|
||||
else {
|
||||
subTableExpression = rootTableExpression;
|
||||
subRootTableKeyColumnNames = new String[ columnSpan ];
|
||||
System.arraycopy( rootTableKeyColumnNames, columnPosition, subRootTableKeyColumnNames, 0, columnSpan );
|
||||
}
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildEmbeddedAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
this,
|
||||
subCompositeType,
|
||||
subTableExpression,
|
||||
subRootTableKeyColumnNames,
|
||||
propertyAccess,
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
creationProcess
|
||||
);
|
||||
|
||||
columnPosition += columnSpan;
|
||||
}
|
||||
else if ( subtype instanceof CollectionType ) {
|
||||
final EntityPersister entityPersister = creationProcess.getEntityPersister( bootDescriptor.getOwner()
|
||||
.getEntityName() );
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildPluralAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
entityPersister,
|
||||
propertyAccess,
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
compositeType.getFetchMode( attributeIndex ),
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
else if ( subtype instanceof EntityType ) {
|
||||
final EntityPersister entityPersister = creationProcess.getEntityPersister( bootDescriptor.getOwner()
|
||||
.getEntityName() );
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildSingularAssociationAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
navigableRole.append( bootPropertyDescriptor.getName() ),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
entityPersister,
|
||||
entityPersister,
|
||||
(EntityType) subtype,
|
||||
getRepresentationStrategy().resolvePropertyAccess( bootPropertyDescriptor ),
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
creationProcess
|
||||
);
|
||||
columnPosition += bootPropertyDescriptor.getColumnSpan();
|
||||
}
|
||||
else {
|
||||
throw new MappingException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Unable to determine attribute nature : %s#%s",
|
||||
bootDescriptor.getOwner().getEntityName(),
|
||||
bootPropertyDescriptor.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
addAttribute( (SingularAttributeMapping) attributeMapping );
|
||||
|
||||
attributeIndex++;
|
||||
}
|
||||
|
||||
// We need the attribute mapping types to finish initialization first before we can build the column mappings
|
||||
creationProcess.registerInitializationCallback(
|
||||
"EmbeddableMappingType(" + navigableRole + ")#initColumnMappings",
|
||||
this::initColumnMappings
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static String getTableIdentifierExpression(Table table, JdbcEnvironment jdbcEnvironment) {
|
||||
return jdbcEnvironment
|
||||
.getQualifiedObjectNameFormatter().format(
|
||||
table.getQualifiedTableName(),
|
||||
jdbcEnvironment.getDialect()
|
||||
);
|
||||
}
|
||||
|
||||
private boolean initColumnMappings() {
|
||||
this.selectableMappings = SelectableMappingsImpl.from( this );
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addAttribute(SingularAttributeMapping attributeMapping) {
|
||||
// check if we've already seen this attribute...
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping previous = attributeMappings.get( i );
|
||||
if ( attributeMapping.getAttributeName().equals( previous.getAttributeName() ) ) {
|
||||
attributeMappings.set( i, attributeMapping );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
attributeMappings.add( attributeMapping );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
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.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class IdClassRepresentationStrategy implements EmbeddableRepresentationStrategy {
|
||||
private final JavaType<?> idClassType;
|
||||
private final EmbeddableInstantiator instantiator;
|
||||
|
||||
public IdClassRepresentationStrategy(IdClassEmbeddable idClassEmbeddable) {
|
||||
this.idClassType = idClassEmbeddable.getMappedJavaTypeDescriptor();
|
||||
this.instantiator = new EmbeddableInstantiatorPojoStandard( () -> idClassEmbeddable, idClassType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableInstantiator getInstantiator() {
|
||||
return instantiator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepresentationMode getMode() {
|
||||
return RepresentationMode.POJO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReflectionOptimizer getReflectionOptimizer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType<?> getMappedJavaTypeDescriptor() {
|
||||
return idClassType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyAccess resolvePropertyAccess(Property bootAttributeDescriptor) {
|
||||
return PropertyAccessStrategyMixedImpl.INSTANCE.buildPropertyAccess(
|
||||
idClassType.getJavaTypeClass(),
|
||||
bootAttributeDescriptor.getName()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -53,27 +53,27 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
|||
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.GeneratedValueResolver;
|
||||
import org.hibernate.metamodel.mapping.ModelPartContainer;
|
||||
import org.hibernate.metamodel.mapping.PropertyBasedMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectableMappings;
|
||||
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.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.GeneratedValueResolver;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.ModelPartContainer;
|
||||
import org.hibernate.metamodel.mapping.NonTransientException;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.PropertyBasedMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
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.model.convert.spi.BasicValueConverter;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
|
@ -82,7 +82,6 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.Joinable;
|
||||
import org.hibernate.persister.walking.internal.FetchOptionsHelper;
|
||||
import org.hibernate.property.access.internal.ChainedPropertyAccessImpl;
|
||||
import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||
|
@ -98,7 +97,6 @@ import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
|
|||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
|
||||
import org.hibernate.type.spi.CompositeTypeImplementor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -141,10 +139,9 @@ public class MappingModelCreationHelper {
|
|||
entityPersister,
|
||||
attributeName,
|
||||
embeddable,
|
||||
attributeMetadataAccess,
|
||||
propertyAccess,
|
||||
rootTableName,
|
||||
creationProcess.getCreationContext().getSessionFactory()
|
||||
creationProcess
|
||||
),
|
||||
creationProcess
|
||||
);
|
||||
|
@ -161,78 +158,88 @@ public class MappingModelCreationHelper {
|
|||
PersistentClass bootEntityDescriptor,
|
||||
BiConsumer<String,SingularAttributeMapping> idSubAttributeConsumer,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
final Component bootIdClassComponent = (Component) bootEntityDescriptor.getIdentifier();
|
||||
final Component bootVirtualComponent;
|
||||
if ( bootEntityDescriptor.getIdentifierMapper() == null ) {
|
||||
// If there is no id-class, there apparently also is no id mapper
|
||||
bootVirtualComponent = bootIdClassComponent;
|
||||
}
|
||||
else {
|
||||
bootVirtualComponent = bootEntityDescriptor.getIdentifierMapper();
|
||||
}
|
||||
final EmbeddableMappingType embeddableMappingType = EmbeddableMappingType.from(
|
||||
bootVirtualComponent,
|
||||
(CompositeType) bootVirtualComponent.getType(),
|
||||
return new NonAggregatedIdentifierMappingImpl(
|
||||
entityPersister,
|
||||
bootEntityDescriptor.getRootClass(),
|
||||
rootTableName,
|
||||
rootTableKeyColumnNames,
|
||||
attributeMappingType -> {
|
||||
final PropertyAccess propertyAccess = PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess(
|
||||
null,
|
||||
EntityIdentifierMapping.ROLE_LOCAL_NAME
|
||||
);
|
||||
final StateArrayContributorMetadataAccess attributeMetadataAccess = getStateArrayContributorMetadataAccess(
|
||||
propertyAccess
|
||||
);
|
||||
|
||||
final EmbeddableMappingType idClassType;
|
||||
if ( bootIdClassComponent != bootVirtualComponent ) {
|
||||
idClassType = EmbeddableMappingType.from(
|
||||
bootIdClassComponent,
|
||||
(CompositeType) bootIdClassComponent.getType(),
|
||||
rootTableName,
|
||||
rootTableKeyColumnNames,
|
||||
idClassEmbeddableType -> new EmbeddedAttributeMapping(
|
||||
"{id-class}",
|
||||
entityPersister.getNavigableRole()
|
||||
.append( EntityIdentifierMapping.ROLE_LOCAL_NAME )
|
||||
.append( "{id-class}" ),
|
||||
-1,
|
||||
null,
|
||||
attributeMetadataAccess,
|
||||
(String) null,
|
||||
FetchTiming.IMMEDIATE,
|
||||
FetchStyle.JOIN,
|
||||
idClassEmbeddableType,
|
||||
entityPersister,
|
||||
propertyAccess,
|
||||
null
|
||||
),
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
else {
|
||||
idClassType = attributeMappingType;
|
||||
}
|
||||
return new NonAggregatedIdentifierMappingImpl(
|
||||
attributeMappingType,
|
||||
entityPersister,
|
||||
idClassType,
|
||||
attributeMetadataAccess,
|
||||
rootTableName,
|
||||
creationProcess
|
||||
);
|
||||
},
|
||||
creationProcess
|
||||
);
|
||||
|
||||
// Inject the model part also in the composite type of the id-class, because that is what we actually "instantiate"
|
||||
// which needs the model part for instantiation
|
||||
final CompositeIdentifierMapping compositeIdentifierMapping = (CompositeIdentifierMapping) embeddableMappingType.getEmbeddedValueMapping();
|
||||
( (CompositeTypeImplementor) bootEntityDescriptor.getIdentifier().getType() ).injectMappingModelPart(
|
||||
(EmbeddableValuedModelPart) compositeIdentifierMapping,
|
||||
creationProcess
|
||||
);
|
||||
return compositeIdentifierMapping;
|
||||
// final Component bootIdClassComponent = (Component) bootEntityDescriptor.getIdentifier();
|
||||
// final Component bootVirtualComponent;
|
||||
// if ( bootEntityDescriptor.getIdentifierMapper() == null ) {
|
||||
// // If there is no id-class, there apparently also is no id mapper
|
||||
// bootVirtualComponent = bootIdClassComponent;
|
||||
// }
|
||||
// else {
|
||||
// bootVirtualComponent = bootEntityDescriptor.getIdentifierMapper();
|
||||
// }
|
||||
//
|
||||
// final EmbeddableMappingType embeddableMappingType = EmbeddableMappingType.from(
|
||||
// bootVirtualComponent,
|
||||
// (CompositeType) bootVirtualComponent.getType(),
|
||||
// rootTableName,
|
||||
// rootTableKeyColumnNames,
|
||||
// attributeMappingType -> {
|
||||
// final PropertyAccess propertyAccess = PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess(
|
||||
// null,
|
||||
// EntityIdentifierMapping.ROLE_LOCAL_NAME
|
||||
// );
|
||||
// final StateArrayContributorMetadataAccess attributeMetadataAccess = getStateArrayContributorMetadataAccess(
|
||||
// propertyAccess
|
||||
// );
|
||||
//
|
||||
// final EmbeddableMappingType idClassType;
|
||||
// if ( bootIdClassComponent != bootVirtualComponent ) {
|
||||
// idClassType = EmbeddableMappingType.from(
|
||||
// bootIdClassComponent,
|
||||
// (CompositeType) bootIdClassComponent.getType(),
|
||||
// rootTableName,
|
||||
// rootTableKeyColumnNames,
|
||||
// idClassEmbeddableType -> new EmbeddedAttributeMapping(
|
||||
// "{id-class}",
|
||||
// entityPersister.getNavigableRole()
|
||||
// .append( EntityIdentifierMapping.ROLE_LOCAL_NAME )
|
||||
// .append( "{id-class}" ),
|
||||
// -1,
|
||||
// null,
|
||||
// attributeMetadataAccess,
|
||||
// (String) null,
|
||||
// FetchTiming.IMMEDIATE,
|
||||
// FetchStyle.JOIN,
|
||||
// idClassEmbeddableType,
|
||||
// entityPersister,
|
||||
// propertyAccess,
|
||||
// null
|
||||
// ),
|
||||
// creationProcess
|
||||
// );
|
||||
// }
|
||||
// else {
|
||||
// idClassType = attributeMappingType;
|
||||
// }
|
||||
// return new NonAggregatedIdentifierMappingImpl(
|
||||
// attributeMappingType,
|
||||
// entityPersister,
|
||||
// idClassType,
|
||||
// attributeMetadataAccess,
|
||||
// rootTableName,
|
||||
// creationProcess
|
||||
// );
|
||||
// },
|
||||
// creationProcess
|
||||
// );
|
||||
//
|
||||
// // Inject the model part also in the composite type of the id-class, because that is what we actually "instantiate"
|
||||
// // which needs the model part for instantiation
|
||||
//// final CompositeIdentifierMapping compositeIdentifierMapping = (CompositeIdentifierMapping) virtualIdEmbeddable.getEmbeddedValueMapping();
|
||||
//// ( (CompositeTypeImplementor) virtualIdSource.getType() ).injectMappingModelPart(
|
||||
//// (EmbeddableValuedModelPart) compositeIdentifierMapping,
|
||||
//// creationProcess
|
||||
//// );
|
||||
//
|
||||
// return compositeIdentifierMapping;
|
||||
}
|
||||
|
||||
|
||||
|
@ -510,54 +517,58 @@ public class MappingModelCreationHelper {
|
|||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected static StateArrayContributorMetadataAccess getStateArrayContributorMetadataAccess(
|
||||
PropertyAccess propertyAccess) {
|
||||
return entityMappingType -> new StateArrayContributorMetadata() {
|
||||
public static StateArrayContributorMetadataAccess getStateArrayContributorMetadataAccess(PropertyAccess propertyAccess) {
|
||||
return new StateArrayContributorMetadataAccess() {
|
||||
final StateArrayContributorMetadata contributorMetadata = new StateArrayContributorMetadata() {
|
||||
private final MutabilityPlan mutabilityPlan = ImmutableMutabilityPlan.INSTANCE;
|
||||
|
||||
private final MutabilityPlan mutabilityPlan = ImmutableMutabilityPlan.INSTANCE;
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutabilityPlan getMutabilityPlan() {
|
||||
return mutabilityPlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInDirtyChecking() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInOptimisticLocking() {
|
||||
// todo (6.0) : do not sure this is correct
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CascadeStyle getCascadeStyle() {
|
||||
// todo (6.0) : do not sure this is correct
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutabilityPlan getMutabilityPlan() {
|
||||
return mutabilityPlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInDirtyChecking() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInOptimisticLocking() {
|
||||
// todo (6.0) : do not sure this is correct
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CascadeStyle getCascadeStyle() {
|
||||
// todo (6.0) : do not sure this is correct
|
||||
return null;
|
||||
public StateArrayContributorMetadata resolveAttributeMetadata(EntityMappingType entityMappingType) {
|
||||
return contributorMetadata;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.IndexedConsumer;
|
||||
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||
import org.hibernate.sql.results.graph.FetchOptions;
|
||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface NonAggregatedIdentifierMapping extends CompositeIdentifierMapping, EmbeddableValuedFetchable, FetchOptions {
|
||||
IdClassEmbeddable getIdClassEmbeddable();
|
||||
VirtualIdEmbeddable getVirtualIdEmbeddable();
|
||||
|
||||
IdentifierValueMapper getIdentifierValueMapper();
|
||||
|
||||
/**
|
||||
* Think of an AttributeConverter for id values. Handles representation
|
||||
* difference between virtual and id-class mappings
|
||||
*/
|
||||
interface IdentifierValueMapper extends IEmbeddableMappingType {
|
||||
EmbeddableValuedModelPart getEmbeddedPart();
|
||||
|
||||
Object getIdentifier(Object entity, SharedSessionContractImplementor session);
|
||||
void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session);
|
||||
|
||||
default void forEachAttribute(IndexedConsumer<SingularAttributeMapping> consumer) {
|
||||
getEmbeddedPart().getEmbeddableTypeDescriptor().forEachAttributeMapping( (IndexedConsumer) consumer );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,16 +14,16 @@ import org.hibernate.engine.spi.PersistenceContext;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
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.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.SelectableMappings;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
|
@ -46,44 +46,105 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
|
|||
* @author Steve Ebersole
|
||||
* @apiNote Technically a MapsId id does not have to be composite; we still handle that this class however
|
||||
*/
|
||||
public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentifierMapping {
|
||||
public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentifierMapping implements NonAggregatedIdentifierMapping {
|
||||
private final VirtualIdEmbeddable virtualIdEmbeddable;
|
||||
private final IdClassEmbeddable idClassEmbeddable;
|
||||
|
||||
private final EmbeddableMappingType mappedIdEmbeddableType;
|
||||
private final IdentifierValueMapper identifierValueMapper;
|
||||
|
||||
public NonAggregatedIdentifierMappingImpl(
|
||||
EmbeddableMappingType embeddableDescriptor,
|
||||
EntityMappingType entityMapping,
|
||||
EmbeddableMappingType mappedIdEmbeddableType,
|
||||
StateArrayContributorMetadataAccess attributeMetadataAccess,
|
||||
EntityPersister entityPersister,
|
||||
RootClass bootEntityDescriptor,
|
||||
String rootTableName,
|
||||
String[] rootTableKeyColumnNames,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
super(
|
||||
attributeMetadataAccess,
|
||||
embeddableDescriptor,
|
||||
entityMapping,
|
||||
rootTableName,
|
||||
creationProcess.getCreationContext().getSessionFactory()
|
||||
);
|
||||
super( entityPersister, rootTableName, creationProcess );
|
||||
if ( bootEntityDescriptor.getIdentifierMapper() == null
|
||||
|| bootEntityDescriptor.getIdentifierMapper() == bootEntityDescriptor.getIdentifier() ) {
|
||||
// cid -> getIdentifier
|
||||
// idClass -> null
|
||||
final Component virtualIdSource = (Component) bootEntityDescriptor.getIdentifier();
|
||||
|
||||
this.mappedIdEmbeddableType = mappedIdEmbeddableType;
|
||||
virtualIdEmbeddable = new VirtualIdEmbeddable(
|
||||
virtualIdSource,
|
||||
this,
|
||||
entityPersister,
|
||||
rootTableName,
|
||||
rootTableKeyColumnNames,
|
||||
creationProcess
|
||||
);
|
||||
idClassEmbeddable = null;
|
||||
identifierValueMapper = virtualIdEmbeddable;
|
||||
}
|
||||
else {
|
||||
// cid = getIdentifierMapper
|
||||
// idClass = getIdentifier
|
||||
final Component virtualIdSource = bootEntityDescriptor.getIdentifierMapper();
|
||||
final Component idClassSource = (Component) bootEntityDescriptor.getIdentifier();
|
||||
|
||||
virtualIdEmbeddable = new VirtualIdEmbeddable(
|
||||
virtualIdSource,
|
||||
this,
|
||||
entityPersister,
|
||||
rootTableName,
|
||||
rootTableKeyColumnNames,
|
||||
creationProcess
|
||||
);
|
||||
idClassEmbeddable = new IdClassEmbeddable(
|
||||
idClassSource,
|
||||
bootEntityDescriptor,
|
||||
this,
|
||||
entityPersister,
|
||||
rootTableName,
|
||||
rootTableKeyColumnNames,
|
||||
virtualIdEmbeddable,
|
||||
creationProcess
|
||||
);
|
||||
identifierValueMapper = idClassEmbeddable;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEmbeddableMappingType getMappedType() {
|
||||
return virtualIdEmbeddable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEmbeddableMappingType getPartMappingType() {
|
||||
return getMappedType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdClassEmbeddable getIdClassEmbeddable() {
|
||||
return idClassEmbeddable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualIdEmbeddable getVirtualIdEmbeddable() {
|
||||
return virtualIdEmbeddable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierValueMapper getIdentifierValueMapper() {
|
||||
return identifierValueMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasContainingClass() {
|
||||
return mappedIdEmbeddableType != getEmbeddableTypeDescriptor();
|
||||
return identifierValueMapper != getEmbeddableTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getMappedIdEmbeddableTypeDescriptor() {
|
||||
return mappedIdEmbeddableType;
|
||||
public IEmbeddableMappingType getMappedIdEmbeddableTypeDescriptor() {
|
||||
return identifierValueMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
if ( hasContainingClass() ) {
|
||||
final Object[] result = new Object[mappedIdEmbeddableType.getAttributeMappings().size()];
|
||||
for ( int i = 0; i < mappedIdEmbeddableType.getAttributeMappings().size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = mappedIdEmbeddableType.getAttributeMappings().get( i );
|
||||
final Object[] result = new Object[ identifierValueMapper.getAttributeMappings().size()];
|
||||
for ( int i = 0; i < identifierValueMapper.getAttributeMappings().size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = identifierValueMapper.getAttributeMappings().get( i );
|
||||
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
result[i] = attributeMapping.disassemble( o, session );
|
||||
}
|
||||
|
@ -103,8 +164,8 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
SharedSessionContractImplementor session) {
|
||||
if ( hasContainingClass() ) {
|
||||
int span = 0;
|
||||
for ( int i = 0; i < mappedIdEmbeddableType.getAttributeMappings().size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = mappedIdEmbeddableType.getAttributeMappings().get( i );
|
||||
for ( int i = 0; i < identifierValueMapper.getAttributeMappings().size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = identifierValueMapper.getAttributeMappings().get( i );
|
||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
||||
|
@ -147,7 +208,7 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
getContainingTableExpression()
|
||||
);
|
||||
int offset = 0;
|
||||
for ( AttributeMapping attributeMapping : mappedIdEmbeddableType.getAttributeMappings() ) {
|
||||
for ( AttributeMapping attributeMapping : identifierValueMapper.getAttributeMappings() ) {
|
||||
offset += attributeMapping.forEachSelectable(
|
||||
offset,
|
||||
(columnIndex, selection) -> {
|
||||
|
@ -184,12 +245,12 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
@Override
|
||||
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
|
||||
if ( hasContainingClass() ) {
|
||||
final Object id = mappedIdEmbeddableType.getRepresentationStrategy().getInstantiator().instantiate(
|
||||
final Object id = identifierValueMapper.getRepresentationStrategy().getInstantiator().instantiate(
|
||||
null,
|
||||
sessionFactory
|
||||
);
|
||||
final List<AttributeMapping> attributeMappings = getEmbeddableTypeDescriptor().getAttributeMappings();
|
||||
final List<AttributeMapping> idClassAttributeMappings = mappedIdEmbeddableType.getAttributeMappings();
|
||||
final List<AttributeMapping> idClassAttributeMappings = identifierValueMapper.getAttributeMappings();
|
||||
final Object[] propertyValues = new Object[attributeMappings.size()];
|
||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
|
@ -222,7 +283,7 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
propertyValues[i] = o;
|
||||
}
|
||||
}
|
||||
mappedIdEmbeddableType.setPropertyValues( id, propertyValues );
|
||||
identifierValueMapper.setPropertyValues( id, propertyValues );
|
||||
return id;
|
||||
}
|
||||
else {
|
||||
|
@ -232,7 +293,7 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
|
||||
@Override
|
||||
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
||||
final List<AttributeMapping> mappedIdAttributeMappings = mappedIdEmbeddableType.getAttributeMappings();
|
||||
final List<AttributeMapping> mappedIdAttributeMappings = identifierValueMapper.getAttributeMappings();
|
||||
final Object[] propertyValues = new Object[mappedIdAttributeMappings.size()];
|
||||
final SessionFactoryImplementor factory = session.getFactory();
|
||||
getEmbeddableTypeDescriptor().forEachAttributeMapping(
|
||||
|
@ -271,10 +332,10 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
assert domainValue instanceof Object[];
|
||||
|
||||
final Object[] values = (Object[]) domainValue;
|
||||
assert values.length == mappedIdEmbeddableType.getAttributeMappings().size();
|
||||
assert values.length == identifierValueMapper.getAttributeMappings().size();
|
||||
|
||||
for ( int i = 0; i < mappedIdEmbeddableType.getAttributeMappings().size(); i++ ) {
|
||||
final AttributeMapping attribute = mappedIdEmbeddableType.getAttributeMappings().get( i );
|
||||
for ( int i = 0; i < identifierValueMapper.getAttributeMappings().size(); i++ ) {
|
||||
final AttributeMapping attribute = identifierValueMapper.getAttributeMappings().get( i );
|
||||
attribute.breakDownJdbcValues( values[ i ], valueConsumer, session );
|
||||
}
|
||||
}
|
||||
|
@ -284,8 +345,8 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
for ( int i = 0; i < mappedIdEmbeddableType.getAttributeMappings().size(); i++ ) {
|
||||
mappedIdEmbeddableType.getAttributeMappings().get( i ).applySqlSelections( navigablePath, tableGroup, creationState );
|
||||
for ( int i = 0; i < identifierValueMapper.getAttributeMappings().size(); i++ ) {
|
||||
identifierValueMapper.getAttributeMappings().get( i ).applySqlSelections( navigablePath, tableGroup, creationState );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,8 +356,8 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState,
|
||||
BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
|
||||
for ( int i = 0; i < mappedIdEmbeddableType.getAttributeMappings().size(); i++ ) {
|
||||
mappedIdEmbeddableType.getAttributeMappings().get( i ).applySqlSelections(
|
||||
for ( int i = 0; i < identifierValueMapper.getAttributeMappings().size(); i++ ) {
|
||||
identifierValueMapper.getAttributeMappings().get( i ).applySqlSelections(
|
||||
navigablePath,
|
||||
tableGroup,
|
||||
creationState,
|
||||
|
@ -320,6 +381,6 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
|
||||
@Override
|
||||
public int getNumberOfFetchables() {
|
||||
return mappedIdEmbeddableType.getNumberOfFetchables();
|
||||
return identifierValueMapper.getNumberOfFetchables();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import org.hibernate.engine.spi.Mapping;
|
|||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.mapping.Selectable;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
|
@ -80,7 +80,7 @@ public class SelectableMappingsImpl implements SelectableMappings {
|
|||
return new SelectableMappingsImpl( selectableMappings );
|
||||
}
|
||||
|
||||
public static SelectableMappings from(EmbeddableMappingType embeddableMappingType) {
|
||||
public static SelectableMappings from(IEmbeddableMappingType embeddableMappingType) {
|
||||
final int propertySpan = embeddableMappingType.getNumberOfAttributeMappings();
|
||||
final List<SelectableMapping> selectableMappings = CollectionHelper.arrayList( propertySpan );
|
||||
|
||||
|
|
|
@ -0,0 +1,726 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.SharedSessionContract;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.Any;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.IndexedConsumer;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.Selectable;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingModelCreationLogger;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.NonTransientException;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
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.model.domain.NavigableRole;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.type.AnyType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||
import org.hibernate.type.spi.CompositeTypeImplementor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
|
||||
import static org.hibernate.metamodel.mapping.internal.NonAggregatedIdentifierMapping.IdentifierValueMapper;
|
||||
|
||||
/**
|
||||
* Embeddable describing the virtual-id aspect of a non-aggregated composite id
|
||||
*/
|
||||
public class VirtualIdEmbeddable implements IdentifierValueMapper {
|
||||
|
||||
private final NavigableRole navigableRole;
|
||||
private final NonAggregatedIdentifierMapping idMapping;
|
||||
private final JavaType<?> javaType;
|
||||
|
||||
// private final VirtualIdEmbedded embedded;
|
||||
private final VirtualIdRepresentationStrategy representationStrategy;
|
||||
|
||||
private final List<SingularAttributeMapping> attributeMappings;
|
||||
private SelectableMappings selectableMappings;
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
public VirtualIdEmbeddable(
|
||||
Component virtualIdSource,
|
||||
NonAggregatedIdentifierMapping idMapping,
|
||||
EntityPersister identifiedEntityMapping,
|
||||
String rootTableExpression,
|
||||
String[] rootTableKeyColumnNames,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
this.sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
|
||||
this.navigableRole = idMapping.getNavigableRole();
|
||||
this.idMapping = idMapping;
|
||||
this.javaType = identifiedEntityMapping.getJavaTypeDescriptor();
|
||||
|
||||
this.representationStrategy = new VirtualIdRepresentationStrategy( identifiedEntityMapping );
|
||||
|
||||
final CompositeType compositeType = (CompositeType) virtualIdSource.getType();
|
||||
this.attributeMappings = arrayList( (compositeType).getPropertyNames().length );
|
||||
|
||||
// todo (6.0) : can this be a separate VirtualIdEmbedded?
|
||||
( (CompositeTypeImplementor) compositeType ).injectMappingModelPart( idMapping, creationProcess );
|
||||
|
||||
creationProcess.registerInitializationCallback(
|
||||
"VirtualIdEmbeddable(" + navigableRole.getFullPath() + ")#finishInitialization",
|
||||
() -> {
|
||||
try {
|
||||
final boolean finished = finishInitialization(
|
||||
virtualIdSource,
|
||||
compositeType,
|
||||
rootTableExpression,
|
||||
rootTableKeyColumnNames,
|
||||
creationProcess
|
||||
);
|
||||
|
||||
if ( finished ) {
|
||||
return finished;
|
||||
}
|
||||
else {
|
||||
MappingModelCreationLogger.LOGGER.debugf(
|
||||
"VirtualIdEmbeddable(%s) finalization was not able to complete successfully",
|
||||
navigableRole.getFullPath()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
if ( e instanceof NonTransientException ) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
MappingModelCreationLogger.LOGGER.debugf(
|
||||
e,
|
||||
"(DEBUG) Error finalizing VirtualIdEmbeddable(%s)",
|
||||
navigableRole.getFullPath()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public VirtualIdEmbeddable(
|
||||
NonAggregatedIdentifierMapping idMapping,
|
||||
EntityMappingType identifiedEntityMapping,
|
||||
Component bootDescriptor,
|
||||
CompositeType compositeType,
|
||||
String rootTableExpression,
|
||||
String[] rootTableKeyColumnNames,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
this.sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
|
||||
this.navigableRole = idMapping.getNavigableRole();
|
||||
this.idMapping = idMapping;
|
||||
this.javaType = identifiedEntityMapping.getJavaTypeDescriptor();
|
||||
this.attributeMappings = arrayList( compositeType.getPropertyNames().length );
|
||||
|
||||
this.representationStrategy = new VirtualIdRepresentationStrategy( identifiedEntityMapping );
|
||||
|
||||
( (CompositeTypeImplementor) compositeType ).injectMappingModelPart( getEmbeddedValueMapping(), creationProcess );
|
||||
|
||||
creationProcess.registerInitializationCallback(
|
||||
"EmbeddableMappingType(" + navigableRole.getFullPath() + ")#finishInitialization",
|
||||
() -> {
|
||||
try {
|
||||
final boolean finished = finishInitialization(
|
||||
bootDescriptor,
|
||||
compositeType,
|
||||
rootTableExpression,
|
||||
rootTableKeyColumnNames,
|
||||
creationProcess
|
||||
);
|
||||
|
||||
if ( finished ) {
|
||||
return finished;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
if ( e instanceof NonTransientException ) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
MappingModelCreationLogger.LOGGER.debugf(
|
||||
"EmbeddableMappingType(%s) finalization was not able to complete successfully",
|
||||
navigableRole
|
||||
);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// IdentifierValueMapper
|
||||
|
||||
@Override
|
||||
public EmbeddableValuedModelPart getEmbeddedPart() {
|
||||
return idMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
|
||||
return representationStrategy.getInstantiator().instantiate(
|
||||
() -> getPropertyValues( entity ),
|
||||
session.getSessionFactory()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
||||
if ( entity != id ) {
|
||||
setPropertyValues( entity, getPropertyValues( id ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// EmbeddableMappingType
|
||||
|
||||
@Override
|
||||
public NavigableRole getNavigableRole() {
|
||||
return navigableRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPartName() {
|
||||
return idMapping.getPartName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType<?> getMappedJavaTypeDescriptor() {
|
||||
return javaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableValuedModelPart getEmbeddedValueMapping() {
|
||||
return getEmbeddedPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualIdRepresentationStrategy getRepresentationStrategy() {
|
||||
return representationStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getPropertyValues(Object composite) {
|
||||
final Object[] values = new Object[ attributeMappings.size() ];
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final SingularAttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
values[i] = attributeMapping.getPropertyAccess().getGetter().get( composite );
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyValues(Object composite, Object[] resolvedValues) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final SingularAttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
attributeMapping.getPropertyAccess().getSetter().set( composite, resolvedValues[i], sessionFactory );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectableMapping getSelectable(int columnIndex) {
|
||||
return selectableMappings.getSelectable( columnIndex );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(SelectableConsumer consumer) {
|
||||
return selectableMappings.forEachSelectable( 0, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(int offset, SelectableConsumer consumer) {
|
||||
return selectableMappings.forEachSelectable( offset, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJdbcTypeCount() {
|
||||
return selectableMappings.getJdbcTypeCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JdbcMapping> getJdbcMappings() {
|
||||
return selectableMappings.getJdbcMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
||||
return selectableMappings.forEachSelectable(
|
||||
offset,
|
||||
(index, selectable) -> action.accept( index, selectable.getJdbcMapping() )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreateEmptyCompositesEnabled() {
|
||||
// generally we do not want empty composites for identifiers
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfAttributeMappings() {
|
||||
return attributeMappings.size();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public List<AttributeMapping> getAttributeMappings() {
|
||||
return (List) attributeMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAttributeMappings(Consumer<? super AttributeMapping> action) {
|
||||
forEachAttribute( (index, attribute) -> action.accept( attribute ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachAttributeMapping(IndexedConsumer<AttributeMapping> consumer) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
consumer.accept( i, attributeMappings.get( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfFetchables() {
|
||||
return getNumberOfAttributeMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType findContainingEntityMapping() {
|
||||
return idMapping.findContainingEntityMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSubParts(Consumer<ModelPart> consumer, EntityMappingType treatTargetType) {
|
||||
attributeMappings.forEach( consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final SingularAttributeMapping attribute = attributeMappings.get( i );
|
||||
if ( attribute.getAttributeName().equals( name ) ) {
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(NavigablePath navigablePath, TableGroup tableGroup, String resultVariable, DomainResultCreationState creationState) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachJdbcValue(
|
||||
Object value,
|
||||
Clause clause,
|
||||
int offset,
|
||||
JdbcValuesConsumer valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
int span = 0;
|
||||
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
if ( attributeMapping instanceof PluralAttributeMapping ) {
|
||||
continue;
|
||||
}
|
||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
span += attributeMapping.forEachJdbcValue( o, clause, span + offset, valuesConsumer, session );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
||||
attributeMappings.forEach( (attribute) -> {
|
||||
final Object attributeValue = attribute.getValue( domainValue, session );
|
||||
attribute.breakDownJdbcValues( attributeValue, valueConsumer, session );
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
final Object[] result = new Object[ attributeMappings.size() ];
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
result[i] = attributeMapping.disassemble( o, session );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachDisassembledJdbcValue(
|
||||
Object value,
|
||||
Clause clause,
|
||||
int offset,
|
||||
JdbcValuesConsumer valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
final Object[] values = (Object[]) value;
|
||||
int span = 0;
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping mapping = attributeMappings.get( i );
|
||||
span += mapping.forEachDisassembledJdbcValue( values[i], clause, span + offset, valuesConsumer, session );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEmbeddableMappingType createInverseMappingType(
|
||||
EmbeddedAttributeMapping valueMapping,
|
||||
TableGroupProducer declaringTableGroupProducer,
|
||||
SelectableMappings selectableMappings,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
return new EmbeddableMappingType(
|
||||
valueMapping,
|
||||
declaringTableGroupProducer,
|
||||
selectableMappings,
|
||||
this,
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// init
|
||||
|
||||
private boolean finishInitialization(
|
||||
Component bootDescriptor,
|
||||
CompositeType compositeType,
|
||||
String rootTableExpression,
|
||||
String[] rootTableKeyColumnNames,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
final SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
||||
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
|
||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||
final Dialect dialect = jdbcEnvironment.getDialect();
|
||||
|
||||
final Type[] subtypes = compositeType.getSubtypes();
|
||||
|
||||
int attributeIndex = 0;
|
||||
int columnPosition = 0;
|
||||
|
||||
// Reset the attribute mappings that were added in previous attempts
|
||||
this.attributeMappings.clear();
|
||||
|
||||
final Iterator<Property> propertyIterator = bootDescriptor.getPropertyIterator();
|
||||
while ( propertyIterator.hasNext() ) {
|
||||
final Property bootPropertyDescriptor = propertyIterator.next();
|
||||
|
||||
final PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess( bootPropertyDescriptor );
|
||||
|
||||
final AttributeMapping attributeMapping;
|
||||
|
||||
final Type subtype = subtypes[ attributeIndex ];
|
||||
if ( subtype instanceof BasicType ) {
|
||||
final BasicValue basicValue = (BasicValue) bootPropertyDescriptor.getValue();
|
||||
final Selectable selectable = basicValue.getColumn();
|
||||
final String containingTableExpression;
|
||||
final String columnExpression;
|
||||
if ( rootTableKeyColumnNames == null ) {
|
||||
if ( selectable.isFormula() ) {
|
||||
columnExpression = selectable.getTemplate( dialect, creationProcess.getSqmFunctionRegistry() );
|
||||
}
|
||||
else {
|
||||
columnExpression = selectable.getText( dialect );
|
||||
}
|
||||
if ( selectable instanceof Column ) {
|
||||
containingTableExpression = getTableIdentifierExpression(
|
||||
( (Column) selectable ).getValue().getTable(),
|
||||
jdbcEnvironment
|
||||
);
|
||||
}
|
||||
else {
|
||||
containingTableExpression = rootTableExpression;
|
||||
}
|
||||
}
|
||||
else {
|
||||
containingTableExpression = rootTableExpression;
|
||||
columnExpression = rootTableKeyColumnNames[ columnPosition ];
|
||||
}
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
navigableRole.append( bootPropertyDescriptor.getName() ),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
this,
|
||||
(BasicType<?>) subtype,
|
||||
containingTableExpression,
|
||||
columnExpression,
|
||||
selectable.isFormula(),
|
||||
selectable.getCustomReadExpression(),
|
||||
selectable.getCustomWriteExpression(),
|
||||
propertyAccess,
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
creationProcess
|
||||
);
|
||||
|
||||
columnPosition++;
|
||||
}
|
||||
else if ( subtype instanceof AnyType ) {
|
||||
final Any bootValueMapping = (Any) bootPropertyDescriptor.getValue();
|
||||
final AnyType anyType = (AnyType) subtype;
|
||||
|
||||
final boolean nullable = bootValueMapping.isNullable();
|
||||
final boolean insertable = bootPropertyDescriptor.isInsertable();
|
||||
final boolean updateable = bootPropertyDescriptor.isUpdateable();
|
||||
final boolean includeInOptimisticLocking = bootPropertyDescriptor.isOptimisticLocked();
|
||||
final CascadeStyle cascadeStyle = compositeType.getCascadeStyle( attributeIndex );
|
||||
final MutabilityPlan<?> mutabilityPlan;
|
||||
|
||||
if ( updateable ) {
|
||||
mutabilityPlan = new MutabilityPlan<Object>() {
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object deepCopy(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return anyType.deepCopy( value, creationProcess.getCreationContext().getSessionFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SharedSessionContract session) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(Serializable cached, SharedSessionContract session) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
mutabilityPlan = ImmutableMutabilityPlan.INSTANCE;
|
||||
}
|
||||
|
||||
final StateArrayContributorMetadataAccess attributeMetadataAccess = entityMappingType -> new StateArrayContributorMetadata() {
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutabilityPlan<?> getMutabilityPlan() {
|
||||
return mutabilityPlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertable() {
|
||||
return insertable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return updateable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInDirtyChecking() {
|
||||
// todo (6.0) : do not believe this is correct
|
||||
return updateable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedInOptimisticLocking() {
|
||||
return includeInOptimisticLocking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CascadeStyle getCascadeStyle() {
|
||||
return cascadeStyle;
|
||||
}
|
||||
};
|
||||
|
||||
attributeMapping = new DiscriminatedAssociationAttributeMapping(
|
||||
navigableRole.append( bootPropertyDescriptor.getName() ),
|
||||
typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Object.class ),
|
||||
this,
|
||||
attributeIndex,
|
||||
attributeMetadataAccess,
|
||||
bootPropertyDescriptor.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE,
|
||||
propertyAccess,
|
||||
bootPropertyDescriptor,
|
||||
anyType,
|
||||
bootValueMapping,
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
else if ( subtype instanceof CompositeType ) {
|
||||
final CompositeType subCompositeType = (CompositeType) subtype;
|
||||
final int columnSpan = subCompositeType.getColumnSpan( sessionFactory );
|
||||
final String subTableExpression;
|
||||
final String[] subRootTableKeyColumnNames;
|
||||
if ( rootTableKeyColumnNames == null ) {
|
||||
subTableExpression = rootTableExpression;
|
||||
subRootTableKeyColumnNames = null;
|
||||
}
|
||||
else {
|
||||
subTableExpression = rootTableExpression;
|
||||
subRootTableKeyColumnNames = new String[ columnSpan ];
|
||||
System.arraycopy( rootTableKeyColumnNames, columnPosition, subRootTableKeyColumnNames, 0, columnSpan );
|
||||
}
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildEmbeddedAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
this,
|
||||
subCompositeType,
|
||||
subTableExpression,
|
||||
subRootTableKeyColumnNames,
|
||||
propertyAccess,
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
creationProcess
|
||||
);
|
||||
|
||||
columnPosition += columnSpan;
|
||||
}
|
||||
else if ( subtype instanceof CollectionType ) {
|
||||
final EntityPersister entityPersister = creationProcess.getEntityPersister( bootDescriptor.getOwner()
|
||||
.getEntityName() );
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildPluralAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
entityPersister,
|
||||
propertyAccess,
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
compositeType.getFetchMode( attributeIndex ),
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
else if ( subtype instanceof EntityType ) {
|
||||
final EntityPersister entityPersister = creationProcess.getEntityPersister( bootDescriptor.getOwner()
|
||||
.getEntityName() );
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildSingularAssociationAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
navigableRole.append( bootPropertyDescriptor.getName() ),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
entityPersister,
|
||||
entityPersister,
|
||||
(EntityType) subtype,
|
||||
getRepresentationStrategy().resolvePropertyAccess( bootPropertyDescriptor ),
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
creationProcess
|
||||
);
|
||||
columnPosition += bootPropertyDescriptor.getColumnSpan();
|
||||
}
|
||||
else {
|
||||
throw new MappingException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Unable to determine attribute nature : %s#%s",
|
||||
bootDescriptor.getOwner().getEntityName(),
|
||||
bootPropertyDescriptor.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
addAttribute( (SingularAttributeMapping) attributeMapping );
|
||||
|
||||
attributeIndex++;
|
||||
}
|
||||
|
||||
// We need the attribute mapping types to finish initialization first before we can build the column mappings
|
||||
creationProcess.registerInitializationCallback(
|
||||
"EmbeddableMappingType(" + navigableRole + ")#initColumnMappings",
|
||||
this::initColumnMappings
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static String getTableIdentifierExpression(Table table, JdbcEnvironment jdbcEnvironment) {
|
||||
return jdbcEnvironment
|
||||
.getQualifiedObjectNameFormatter().format(
|
||||
table.getQualifiedTableName(),
|
||||
jdbcEnvironment.getDialect()
|
||||
);
|
||||
}
|
||||
|
||||
private boolean initColumnMappings() {
|
||||
this.selectableMappings = SelectableMappingsImpl.from( this );
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addAttribute(SingularAttributeMapping attributeMapping) {
|
||||
// check if we've already seen this attribute...
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping previous = attributeMappings.get( i );
|
||||
if ( attributeMapping.getAttributeName().equals( previous.getAttributeName() ) ) {
|
||||
attributeMappings.set( i, attributeMapping );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
attributeMappings.add( attributeMapping );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.EntityInstantiator;
|
||||
import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class VirtualIdRepresentationStrategy implements EmbeddableRepresentationStrategy {
|
||||
private final EntityMappingType entityMappingType;
|
||||
private final EmbeddableInstantiator instantiator;
|
||||
|
||||
public VirtualIdRepresentationStrategy(EntityMappingType entityMappingType) {
|
||||
this.entityMappingType = entityMappingType;
|
||||
instantiator = new InstantiatorAdapter( entityMappingType.getRepresentationStrategy().getInstantiator() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableInstantiator getInstantiator() {
|
||||
return instantiator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepresentationMode getMode() {
|
||||
return RepresentationMode.POJO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReflectionOptimizer getReflectionOptimizer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType<?> getMappedJavaTypeDescriptor() {
|
||||
return entityMappingType.getMappedJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyAccess resolvePropertyAccess(Property bootAttributeDescriptor) {
|
||||
return PropertyAccessStrategyMixedImpl.INSTANCE.buildPropertyAccess(
|
||||
entityMappingType.getMappedJavaTypeDescriptor().getJavaTypeClass(),
|
||||
bootAttributeDescriptor.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private static class InstantiatorAdapter implements EmbeddableInstantiator {
|
||||
private final EntityInstantiator entityInstantiator;
|
||||
|
||||
public InstantiatorAdapter(EntityInstantiator entityInstantiator) {
|
||||
this.entityInstantiator = entityInstantiator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiate(Supplier<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory) {
|
||||
return entityInstantiator.instantiate( sessionFactory );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) {
|
||||
return entityInstantiator.isInstance( object, sessionFactory );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) {
|
||||
return entityInstantiator.isSameClass( object, sessionFactory );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping.ordering.ast;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.AbstractDomainPath;
|
||||
import org.hibernate.metamodel.mapping.ordering.TranslationContext;
|
||||
|
@ -52,7 +52,7 @@ public class DomainPathContinuation extends AbstractDomainPath {
|
|||
boolean isTerminal,
|
||||
TranslationContext translationContext) {
|
||||
if ( referencedModelPart instanceof EmbeddableValuedModelPart ) {
|
||||
final EmbeddableMappingType embeddableMappingType = (EmbeddableMappingType) referencedModelPart.getPartMappingType();
|
||||
final IEmbeddableMappingType embeddableMappingType = (IEmbeddableMappingType) referencedModelPart.getPartMappingType();
|
||||
final ModelPart subPart = embeddableMappingType.findSubPart( name, null );
|
||||
if ( subPart == null ) {
|
||||
throw new PathResolutionException(
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.function.Supplier;
|
|||
import org.hibernate.Incubating;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,6 @@ public interface ManagedTypeRepresentationResolver {
|
|||
*/
|
||||
EmbeddableRepresentationStrategy resolveStrategy(
|
||||
Component bootDescriptor,
|
||||
Supplier<EmbeddableMappingType> runtimeDescriptor,
|
||||
Supplier<IEmbeddableMappingType> runtimeDescriptor,
|
||||
RuntimeModelCreationContext creationContext);
|
||||
}
|
||||
|
|
|
@ -21,10 +21,10 @@ import org.hibernate.internal.util.collections.Stack;
|
|||
import org.hibernate.internal.util.collections.StandardStack;
|
||||
import org.hibernate.metamodel.mapping.Association;
|
||||
import org.hibernate.metamodel.mapping.AssociationKey;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.NonAggregatedIdentifierMappingImpl;
|
||||
import org.hibernate.query.EntityIdentifierNavigablePath;
|
||||
|
@ -334,8 +334,8 @@ public class DomainResultCreationStateImpl
|
|||
if ( fetchable instanceof Association && fetchable.getMappedFetchOptions().getTiming() == FetchTiming.DELAYED ) {
|
||||
final Association association = (Association) fetchable;
|
||||
final ForeignKeyDescriptor foreignKeyDescriptor = association.getForeignKeyDescriptor();
|
||||
if ( foreignKeyDescriptor.getPartMappingType() instanceof EmbeddableMappingType ) {
|
||||
relativePathStack.push( relativePath.append( ( (EmbeddableMappingType) foreignKeyDescriptor.getPartMappingType() ).getPartName() ) );
|
||||
if ( foreignKeyDescriptor.getPartMappingType() instanceof IEmbeddableMappingType ) {
|
||||
relativePathStack.push( relativePath.append( ( (IEmbeddableMappingType) foreignKeyDescriptor.getPartMappingType() ).getPartName() ) );
|
||||
}
|
||||
else {
|
||||
relativePathStack.push( relativePath.append( foreignKeyDescriptor.getPartName() ) );
|
||||
|
|
|
@ -14,8 +14,8 @@ import java.util.function.BiFunction;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
|
@ -61,8 +61,8 @@ public class ImplicitFetchBuilderEntity implements ImplicitFetchBuilder {
|
|||
final Map<NavigablePath, FetchBuilder> fetchBuilders;
|
||||
if ( explicitAssociationKeyFetchBuilder == null ) {
|
||||
final MappingType partMappingType = foreignKeyDescriptor.getPartMappingType();
|
||||
if ( partMappingType instanceof EmbeddableMappingType ) {
|
||||
final EmbeddableMappingType embeddableValuedModelPart = (EmbeddableMappingType) partMappingType;
|
||||
if ( partMappingType instanceof IEmbeddableMappingType ) {
|
||||
final IEmbeddableMappingType embeddableValuedModelPart = (IEmbeddableMappingType) partMappingType;
|
||||
fetchBuilders = new LinkedHashMap<>( embeddableValuedModelPart.getNumberOfFetchables() );
|
||||
embeddableValuedModelPart.visitFetchables(
|
||||
subFetchable -> {
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
|||
import org.hibernate.metamodel.mapping.Bindable;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
|
@ -62,6 +61,7 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
|
|||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityVersionMapping;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||
|
@ -3858,9 +3858,9 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
final int size = groupedExpressions.size();
|
||||
final List<Expression> expressions = new ArrayList<>( size );
|
||||
final MappingModelExpressable<?> mappingModelExpressable = inferrableTypeAccessStack.getCurrent().get();
|
||||
final EmbeddableMappingType embeddableMappingType;
|
||||
final IEmbeddableMappingType embeddableMappingType;
|
||||
if ( mappingModelExpressable instanceof ValueMapping ) {
|
||||
embeddableMappingType = (EmbeddableMappingType) ( (ValueMapping) mappingModelExpressable ).getMappedType();
|
||||
embeddableMappingType = (IEmbeddableMappingType) ( (ValueMapping) mappingModelExpressable ).getMappedType();
|
||||
}
|
||||
else {
|
||||
embeddableMappingType = null;
|
||||
|
|
|
@ -10,14 +10,13 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.metamodel.mapping.Association;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.query.EntityIdentifierNavigablePath;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.TreatedNavigablePath;
|
||||
|
||||
/**
|
||||
* Contract for things that can be the parent of a fetch
|
||||
|
@ -55,7 +54,8 @@ public interface FetchParent extends DomainResultGraphNode {
|
|||
final FetchableContainer referencedMappingContainer = getReferencedMappingContainer();
|
||||
final EntityMappingType fetchableEntityType = fetchable.findContainingEntityMapping();
|
||||
final EntityMappingType fetchParentType;
|
||||
if ( referencedMappingContainer instanceof EmbeddableMappingType || referencedMappingContainer instanceof EmbeddableValuedModelPart ) {
|
||||
if ( referencedMappingContainer instanceof IEmbeddableMappingType
|
||||
|| referencedMappingContainer instanceof EmbeddableValuedModelPart ) {
|
||||
fetchParentType = referencedMappingContainer.findContainingEntityMapping();
|
||||
}
|
||||
else if ( referencedMappingContainer instanceof EntityMappingType ) {
|
||||
|
|
|
@ -9,16 +9,15 @@ package org.hibernate.sql.results.graph.embeddable;
|
|||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
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.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
||||
|
@ -63,7 +62,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
this.embeddedModelPartDescriptor = resultDescriptor.getReferencedMappingContainer();
|
||||
this.fetchParentAccess = fetchParentAccess;
|
||||
|
||||
final EmbeddableMappingType embeddableTypeDescriptor = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor();
|
||||
final IEmbeddableMappingType embeddableTypeDescriptor = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor();
|
||||
final int numOfAttrs = embeddableTypeDescriptor.getNumberOfAttributeMappings();
|
||||
this.resolvedValues = new Object[ numOfAttrs ];
|
||||
this.assemblerMap = new IdentityHashMap<>( numOfAttrs );
|
||||
|
@ -143,7 +142,7 @@ 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 IEmbeddableMappingType embeddableTypeDescriptor = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor();
|
||||
final EmbeddableRepresentationStrategy representationStrategy;
|
||||
if ( embeddedModelPartDescriptor instanceof CompositeIdentifierMapping ) {
|
||||
representationStrategy = ( (CompositeIdentifierMapping) embeddedModelPartDescriptor ).getMappedIdEmbeddableTypeDescriptor()
|
||||
|
@ -258,7 +257,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
}
|
||||
|
||||
private void setPropertyValuesOnTarget(Object compositeInstance, SharedSessionContractImplementor session) {
|
||||
final EmbeddableMappingType embeddableTypeDescriptor;
|
||||
final IEmbeddableMappingType embeddableTypeDescriptor;
|
||||
if ( embeddedModelPartDescriptor instanceof CompositeIdentifierMapping ) {
|
||||
final CompositeIdentifierMapping compositeIdentifierMapping = (CompositeIdentifierMapping) this.embeddedModelPartDescriptor;
|
||||
embeddableTypeDescriptor = compositeIdentifierMapping.getMappedIdEmbeddableTypeDescriptor();
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.DomainResultGraphNode;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -25,5 +25,5 @@ public interface EmbeddableResultGraphNode extends DomainResultGraphNode, FetchP
|
|||
EmbeddableValuedModelPart getReferencedMappingContainer();
|
||||
|
||||
@Override
|
||||
EmbeddableMappingType getReferencedMappingType();
|
||||
IEmbeddableMappingType getReferencedMappingType();
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||
|
@ -93,8 +93,8 @@ public class EmbeddableFetchImpl extends AbstractFetchParent implements Embeddab
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getFetchContainer() {
|
||||
return (EmbeddableMappingType) super.getFetchContainer();
|
||||
public IEmbeddableMappingType getFetchContainer() {
|
||||
return (IEmbeddableMappingType) super.getFetchContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -133,7 +133,7 @@ public class EmbeddableFetchImpl extends AbstractFetchParent implements Embeddab
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getReferencedMappingType() {
|
||||
public IEmbeddableMappingType getReferencedMappingType() {
|
||||
return getFetchContainer();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
package org.hibernate.sql.results.graph.embeddable.internal;
|
||||
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AbstractFetchParent;
|
||||
|
@ -93,8 +93,8 @@ public class EmbeddableForeignKeyResultImpl<T>
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getReferencedMappingType() {
|
||||
return (EmbeddableMappingType) getFetchContainer().getPartMappingType();
|
||||
public IEmbeddableMappingType getReferencedMappingType() {
|
||||
return (IEmbeddableMappingType) getFetchContainer().getPartMappingType();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,8 +103,8 @@ public class EmbeddableForeignKeyResultImpl<T>
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getFetchContainer() {
|
||||
return (EmbeddableMappingType) super.getFetchContainer();
|
||||
public IEmbeddableMappingType getFetchContainer() {
|
||||
return (IEmbeddableMappingType) super.getFetchContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,8 +8,8 @@ package org.hibernate.sql.results.graph.embeddable.internal;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
||||
|
@ -89,8 +89,8 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getFetchContainer() {
|
||||
return (EmbeddableMappingType) super.getFetchContainer();
|
||||
public IEmbeddableMappingType getFetchContainer() {
|
||||
return (IEmbeddableMappingType) super.getFetchContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,7 +99,7 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
|
|||
}
|
||||
|
||||
@Override
|
||||
public EmbeddableMappingType getReferencedMappingType() {
|
||||
public IEmbeddableMappingType getReferencedMappingType() {
|
||||
return getFetchContainer();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.RuntimeMetamodels;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.IEmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||
|
||||
|
@ -100,7 +100,7 @@ public class AttributeOrderingTests {
|
|||
assertThat( theComponentAttrMapping.getAttributeName(), is( "theComponent" ) );
|
||||
assertThat( entityMappingType.getEntityPersister().getPropertyNames()[ 2 ], is( "theComponent" ) );
|
||||
|
||||
final EmbeddableMappingType embeddable = theComponentAttrMapping.getMappedType();
|
||||
final IEmbeddableMappingType embeddable = theComponentAttrMapping.getMappedType();
|
||||
final ArrayList<AttributeMapping> embeddableAttributeMappings = new ArrayList<>( embeddable.getAttributeMappings() );
|
||||
assertThat( embeddableAttributeMappings.get( 0 ).getAttributeName(), is( "nestedAnything" ) );
|
||||
assertThat( embeddableAttributeMappings.get( 1 ).getAttributeName(), is( "nestedName" ) );
|
||||
|
|
Loading…
Reference in New Issue