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:
Steve Ebersole 2021-11-19 14:31:19 -06:00
parent 25d8fda12c
commit 524b46b246
34 changed files with 2103 additions and 289 deletions

View File

@ -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

View File

@ -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() );
}

View File

@ -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() );

View File

@ -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 );

View File

@ -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(

View File

@ -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;

View File

@ -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.
*

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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() {

View File

@ -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);
}

View File

@ -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(

View File

@ -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;
}

View File

@ -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) -> {

View File

@ -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 );
}
}

View File

@ -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()
);
}
}

View File

@ -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;
}
};
}

View File

@ -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 );
}
}
}

View File

@ -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();
}
}

View File

@ -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 );

View File

@ -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 );
}
}

View File

@ -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 );
}
}
}

View File

@ -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(

View File

@ -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);
}

View File

@ -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() ) );

View File

@ -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 -> {

View File

@ -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;

View File

@ -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 ) {

View File

@ -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();

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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" ) );