Introduce `VirtualIdEmbeddable` and `IdClassEmbeddable` + instantiators

More clean-up (Tuplizers!!)

Mostly EntityTuplizer in this commit

Still need to
  - integrate EmbeddableInstantiator work
  - integrate embedded forms.  `VirtualIdEmbeddable` does not really need it as it can use the id-mapping itself as the embedded form.  But `IdClassEmbedded` should really be integrated
  - integrate `VirtualKeyEmbeddable` and `VirtualKeyEmbedded` for use as inverse composite fks
  - share `#finishInit` handling for `EmbeddableMappingType`, `VirtualIdEmbeddable` and `IdClassEmbeddable`
This commit is contained in:
Steve Ebersole 2021-11-22 15:07:24 -06:00
parent bb2b0a6c47
commit d506bb379c
11 changed files with 51 additions and 459 deletions

View File

@ -20,8 +20,6 @@ import org.hibernate.persister.entity.EntityPersister;
* @apiNote Like ManagedTypeRepresentationStrategy itself, incubating because we * @apiNote Like ManagedTypeRepresentationStrategy itself, incubating because we
* currently need to differentiate between strategy for entity/mapped-superclass * currently need to differentiate between strategy for entity/mapped-superclass
* versus strategy for embeddables * versus strategy for embeddables
*
* @author Steve Ebersole
*/ */
@Incubating @Incubating
public interface ManagedTypeRepresentationResolver { public interface ManagedTypeRepresentationResolver {

View File

@ -24,7 +24,7 @@ import org.hibernate.type.descriptor.java.JavaType;
* both IdentifiableType and EmbeddableType types but that requires (planned) * both IdentifiableType and EmbeddableType types but that requires (planned)
* changes to the Hibernate type system that will not happen until a later date * changes to the Hibernate type system that will not happen until a later date
* *
* @author Steve Ebersole * @see ManagedTypeRepresentationResolver
*/ */
@Incubating @Incubating
public interface ManagedTypeRepresentationStrategy { public interface ManagedTypeRepresentationStrategy {

View File

@ -11,8 +11,11 @@ import java.io.Serializable;
/** /**
* Contract for implementors responsible for instantiating entity/component instances. * Contract for implementors responsible for instantiating entity/component instances.
* *
* @author Steve Ebersole * @deprecated (as of 6.0) This contract is no longer used by Hibernate. Implement/use
* {@link org.hibernate.metamodel.spi.Instantiator} instead. See
* {@link org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy}
*/ */
@Deprecated
public interface Instantiator extends Serializable { public interface Instantiator extends Serializable {
/** /**

View File

@ -19,7 +19,10 @@ import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
/** /**
* Defines a POJO-based instantiator for use from the tuplizers. * Defines a POJO-based instantiator for use from the tuplizers.
*
* @deprecated (as of 6.0) Like {@link Instantiator} itself, deprecated.
*/ */
@Deprecated
public class PojoInstantiator implements Instantiator, Serializable { public class PojoInstantiator implements Instantiator, Serializable {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoInstantiator.class.getName() ); private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoInstantiator.class.getName() );
@ -30,6 +33,10 @@ public class PojoInstantiator implements Instantiator, Serializable {
private final boolean embeddedIdentifier; private final boolean embeddedIdentifier;
private final boolean isAbstract; private final boolean isAbstract;
/**
* @deprecated (as of 6.0) See {@link PojoInstantiator}
*/
@Deprecated
public PojoInstantiator( public PojoInstantiator(
Class mappedClass, Class mappedClass,
ReflectionOptimizer.InstantiationOptimizer optimizer, ReflectionOptimizer.InstantiationOptimizer optimizer,
@ -48,10 +55,18 @@ public class PojoInstantiator implements Instantiator, Serializable {
} }
} }
/**
* @deprecated (as of 6.0) See {@link PojoInstantiator}
*/
@Deprecated
public PojoInstantiator(Component component, ReflectionOptimizer.InstantiationOptimizer optimizer) { public PojoInstantiator(Component component, ReflectionOptimizer.InstantiationOptimizer optimizer) {
this( component.getComponentClass(), optimizer ); this( component.getComponentClass(), optimizer );
} }
/**
* @deprecated (as of 6.0) See {@link PojoInstantiator}
*/
@Deprecated
public PojoInstantiator(Class componentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) { public PojoInstantiator(Class componentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) {
this.mappedClass = componentClass; this.mappedClass = componentClass;
this.isAbstract = ReflectHelper.isAbstractClass( mappedClass ); this.isAbstract = ReflectHelper.isAbstractClass( mappedClass );

View File

@ -10,34 +10,19 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.hibernate.EntityNameResolver;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata; import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
import org.hibernate.tuple.Instantiator;
import org.hibernate.type.AssociationType;
import org.hibernate.type.ComponentType; import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
/** /**
@ -48,24 +33,15 @@ import org.hibernate.type.Type;
*/ */
public abstract class AbstractEntityTuplizer implements EntityTuplizer { public abstract class AbstractEntityTuplizer implements EntityTuplizer {
//TODO: currently keeps Getters and Setters (instead of PropertyAccessors) because of the way getGetter() and getSetter() are implemented currently; yuck!
private final EntityMetamodel entityMetamodel; private final EntityMetamodel entityMetamodel;
private final Getter idGetter;
private final Setter idSetter;
protected final Getter[] getters; protected final Getter[] getters;
protected final Setter[] setters; protected final Setter[] setters;
protected final int propertySpan; protected final int propertySpan;
protected final boolean hasCustomAccessors; protected final boolean hasCustomAccessors;
private final Instantiator instantiator;
private final ProxyFactory proxyFactory;
private final CompositeType identifierMapperType;
public Type getIdentifierMapperType() { private EntityPersister entityDescriptor;
return identifierMapperType; private EntityIdentifierMapping identifierMapping;
}
/** /**
* Build an appropriate Getter for the given property. * Build an appropriate Getter for the given property.
@ -87,15 +63,6 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
*/ */
protected abstract Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity); protected abstract Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity);
/**
* Build an appropriate Instantiator for the given mapped entity.
*
* @param mappingInfo The mapping information regarding the mapped entity.
*
* @return An appropriate Instantiator instance.
*/
protected abstract Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass mappingInfo);
/** /**
* Build an appropriate ProxyFactory for the given mapped entity. * Build an appropriate ProxyFactory for the given mapped entity.
* *
@ -115,27 +82,17 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
*/ */
public AbstractEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) { public AbstractEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) {
this.entityMetamodel = entityMetamodel; this.entityMetamodel = entityMetamodel;
if ( !entityMetamodel.getIdentifierProperty().isVirtual() ) {
idGetter = buildPropertyGetter( mappingInfo.getIdentifierProperty(), mappingInfo );
idSetter = buildPropertySetter( mappingInfo.getIdentifierProperty(), mappingInfo );
}
else {
idGetter = null;
idSetter = null;
}
propertySpan = entityMetamodel.getPropertySpan(); propertySpan = entityMetamodel.getPropertySpan();
getters = new Getter[propertySpan]; getters = new Getter[propertySpan];
setters = new Setter[propertySpan]; setters = new Setter[propertySpan];
Iterator itr = mappingInfo.getPropertyClosureIterator(); final Iterator<Property> itr = mappingInfo.getPropertyClosureIterator();
boolean foundCustomAccessor = false; boolean foundCustomAccessor = false;
int i = 0; int i = 0;
while ( itr.hasNext() ) { while ( itr.hasNext() ) {
//TODO: redesign how PropertyAccessors are acquired... //TODO: redesign how PropertyAccessors are acquired...
Property property = (Property) itr.next(); Property property = itr.next();
getters[i] = buildPropertyGetter( property, mappingInfo ); getters[i] = buildPropertyGetter( property, mappingInfo );
setters[i] = buildPropertySetter( property, mappingInfo ); setters[i] = buildPropertySetter( property, mappingInfo );
if ( !property.isBasicPropertyAccessor() ) { if ( !property.isBasicPropertyAccessor() ) {
@ -144,36 +101,6 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
i++; i++;
} }
hasCustomAccessors = foundCustomAccessor; hasCustomAccessors = foundCustomAccessor;
instantiator = buildInstantiator( entityMetamodel, mappingInfo );
// if ( entityMetamodel.isLazy() && !entityMetamodel.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
if ( entityMetamodel.isLazy() ) {
proxyFactory = buildProxyFactory( mappingInfo, idGetter, idSetter );
if ( proxyFactory == null ) {
entityMetamodel.setLazy( false );
}
}
else {
proxyFactory = null;
}
Component mapper = mappingInfo.getIdentifierMapper();
if ( mapper == null ) {
identifierMapperType = null;
mappedIdentifierValueMarshaller = null;
}
else {
identifierMapperType = (CompositeType) mapper.getType();
KeyValue identifier = mappingInfo.getIdentifier();
mappedIdentifierValueMarshaller = buildMappedIdentifierValueMarshaller(
getEntityName(),
getFactory(),
(ComponentType) entityMetamodel.getIdentifierProperty().getType(),
(ComponentType) identifierMapperType,
identifier
);
}
} }
/** /**
@ -191,280 +118,36 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
* *
* @return Any subclass entity-names. * @return Any subclass entity-names.
*/ */
protected Set getSubclassEntityNames() { protected Set<String> getSubclassEntityNames() {
return entityMetamodel.getSubclassEntityNames(); return entityMetamodel.getSubclassEntityNames();
} }
@Override
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
final Object id;
if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
id = entity;
}
else if ( HibernateProxy.class.isInstance( entity ) ) {
id = ( (HibernateProxy) entity ).getHibernateLazyInitializer().getInternalIdentifier();
}
else {
if ( idGetter == null ) {
if ( identifierMapperType == null ) {
throw new HibernateException( "The class has no identifier property: " + getEntityName() );
}
else {
id = mappedIdentifierValueMarshaller.getIdentifier( entity, session );
}
}
else {
id = idGetter.get( entity );
}
}
try {
return id;
}
catch (ClassCastException cce) {
StringBuilder msg = new StringBuilder( "Identifier classes must be serializable. " );
if ( id != null ) {
msg.append( id.getClass().getName() ).append( " is not serializable. " );
}
if ( cce.getMessage() != null ) {
msg.append( cce.getMessage() );
}
throw new ClassCastException( msg.toString() );
}
}
private interface MappedIdentifierValueMarshaller {
Object getIdentifier(Object entity, SharedSessionContractImplementor session);
void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session);
}
private final MappedIdentifierValueMarshaller mappedIdentifierValueMarshaller;
private static MappedIdentifierValueMarshaller buildMappedIdentifierValueMarshaller(
String entityName,
SessionFactoryImplementor sessionFactory,
ComponentType mappedIdClassComponentType,
ComponentType virtualIdComponent,
KeyValue identifier) {
// so basically at this point we know we have a "mapped" composite identifier
// which is an awful way to say that the identifier is represented differently
// in the entity and in the identifier value. The incoming value should
// be an instance of the mapped identifier class (@IdClass) while the incoming entity
// should be an instance of the entity class as defined by metamodel.
//
// However, even within that we have 2 potential scenarios:
// 1) @IdClass types and entity @Id property types match
// - return a NormalMappedIdentifierValueMarshaller
// 2) They do not match
// - return a IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller
boolean wereAllEquivalent = true;
// the sizes being off is a much bigger problem that should have been caught already...
for ( int i = 0; i < virtualIdComponent.getSubtypes().length; i++ ) {
if ( virtualIdComponent.getSubtypes()[i].isEntityType()
&& !mappedIdClassComponentType.getSubtypes()[i].isEntityType() ) {
wereAllEquivalent = false;
break;
}
}
return wereAllEquivalent ?
new NormalMappedIdentifierValueMarshaller( virtualIdComponent, mappedIdClassComponentType ) :
new IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
entityName,
sessionFactory,
virtualIdComponent,
mappedIdClassComponentType,
identifier
);
}
private static class NormalMappedIdentifierValueMarshaller implements MappedIdentifierValueMarshaller {
private final ComponentType virtualIdComponent;
private final ComponentType mappedIdentifierType;
private NormalMappedIdentifierValueMarshaller(
ComponentType virtualIdComponent,
ComponentType mappedIdentifierType) {
this.virtualIdComponent = virtualIdComponent;
this.mappedIdentifierType = mappedIdentifierType;
}
@Override @Override
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) { public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
Object id = mappedIdentifierType.instantiate(); final EntityIdentifierMapping identifierMapping = resolveIdentifierDescriptor();
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity ); return identifierMapping.getIdentifier( entity, session );
mappedIdentifierType.setPropertyValues( id, propertyValues );
return id;
} }
@Override protected EntityIdentifierMapping resolveIdentifierDescriptor() {
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) { if ( identifierMapping == null ) {
virtualIdComponent.setPropertyValues( identifierMapping = resolveEntityDescriptor().getIdentifierMapping();
entity,
mappedIdentifierType.getPropertyValues( id, session )
);
}
} }
private static class IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller return identifierMapping;
implements MappedIdentifierValueMarshaller {
private final String entityName;
private final SessionFactoryImplementor sessionFactory;
private final ComponentType virtualIdComponent;
private final ComponentType mappedIdentifierType;
private final KeyValue identifier;
private IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
String entityName,
SessionFactoryImplementor sessionFactory,
ComponentType virtualIdComponent,
ComponentType mappedIdentifierType,
KeyValue identifier) {
this.sessionFactory = sessionFactory;
this.entityName = entityName;
this.virtualIdComponent = virtualIdComponent;
this.mappedIdentifierType = mappedIdentifierType;
this.identifier = identifier;
} }
@Override private EntityPersister resolveEntityDescriptor() {
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) { if ( entityDescriptor == null ) {
final Object id = mappedIdentifierType.instantiate(); entityDescriptor = getFactory()
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity ); .getRuntimeMetamodels()
final Type[] subTypes = virtualIdComponent.getSubtypes(); .getMappingMetamodel()
final Type[] copierSubTypes = mappedIdentifierType.getSubtypes(); .findEntityDescriptor( getEntityName() );
final int length = subTypes.length;
for ( int i = 0; i < length; i++ ) {
final Type subType = subTypes[i];
if ( propertyValues[i] == null ) {
if ( subType.isAssociationType() ) {
throw new HibernateException( "No part of a composite identifier may be null" );
}
final Property p = ( (Component) identifier ).getProperty( i );
final SimpleValue v = (SimpleValue) p.getValue();
if ( v.getIdentifierGenerator() == null ) {
throw new HibernateException( "No part of a composite identifier may be null" );
}
}
//JPA 2 @MapsId + @IdClass points to the pk of the entity
if ( subType.isAssociationType() && !copierSubTypes[i].isAssociationType() ) {
propertyValues[i] = determineEntityId(
propertyValues[i],
(AssociationType) subType,
session,
sessionFactory
);
}
}
mappedIdentifierType.setPropertyValues( id, propertyValues );
return id;
} }
@Override return entityDescriptor;
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
final Object[] extractedValues = mappedIdentifierType.getPropertyValues( id );
final Object[] injectionValues = new Object[extractedValues.length];
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final MetamodelImplementor metamodel = sessionFactory.getMetamodel();
for ( int i = 0; i < virtualIdComponent.getSubtypes().length; i++ ) {
final Type virtualPropertyType = virtualIdComponent.getSubtypes()[i];
final Type idClassPropertyType = mappedIdentifierType.getSubtypes()[i];
if ( virtualPropertyType.isEntityType() && !idClassPropertyType.isEntityType() ) {
if ( session == null ) {
throw new AssertionError(
"Deprecated version of getIdentifier (no session) was used but session was required"
);
}
final String associatedEntityName = ( (EntityType) virtualPropertyType ).getAssociatedEntityName();
final EntityKey entityKey = session.generateEntityKey(
extractedValues[i],
metamodel.entityPersister( associatedEntityName )
);
// it is conceivable there is a proxy, so check that first
Object association = persistenceContext.getProxy( entityKey );
if ( association == null ) {
// otherwise look for an initialized version
association = persistenceContext.getEntity( entityKey );
if ( association == null ) {
// get the association out of the entity itself
association = metamodel.entityPersister( entityName ).getPropertyValue(
entity,
virtualIdComponent.getPropertyNames()[i]
);
}
}
injectionValues[i] = association;
}
else {
injectionValues[i] = extractedValues[i];
}
}
virtualIdComponent.setPropertyValues( entity, injectionValues );
}
} }
private static Object determineEntityId(
Object entity,
AssociationType associationType,
SharedSessionContractImplementor session,
SessionFactoryImplementor sessionFactory) {
if ( entity == null ) {
return null;
}
if ( entity instanceof HibernateProxy ) {
// entity is a proxy, so we know it is not transient; just return ID from proxy
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getInternalIdentifier();
}
if ( session != null ) {
final EntityEntry pcEntry = session.getPersistenceContextInternal().getEntry( entity );
if ( pcEntry != null ) {
// entity managed; return ID.
return pcEntry.getId();
}
}
final EntityPersister persister = resolveEntityPersister(
entity,
associationType,
session,
sessionFactory
);
return persister.getIdentifier( entity, session );
}
private static EntityPersister resolveEntityPersister(
Object entity,
AssociationType associationType,
SharedSessionContractImplementor session,
SessionFactoryImplementor sessionFactory) {
assert sessionFactory != null;
if ( session != null ) {
return session.getEntityPersister(
associationType.getAssociatedEntityName( sessionFactory ),
entity
);
}
String entityName = null;
final MetamodelImplementor metamodel = sessionFactory.getMetamodel();
for ( EntityNameResolver entityNameResolver : metamodel.getEntityNameResolvers() ) {
entityName = entityNameResolver.resolveEntityName( entity );
if ( entityName != null ) {
break;
}
}
if ( entityName == null ) {
// old fall-back
entityName = entity.getClass().getName();
}
return metamodel.entityPersister( entityName );
}
protected boolean shouldGetAllProperties(Object entity) { protected boolean shouldGetAllProperties(Object entity) {
final BytecodeEnhancementMetadata bytecodeEnhancementMetadata = getEntityMetamodel().getBytecodeEnhancementMetadata(); final BytecodeEnhancementMetadata bytecodeEnhancementMetadata = getEntityMetamodel().getBytecodeEnhancementMetadata();
@ -477,18 +160,14 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
@Override @Override
public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SharedSessionContractImplementor session) { public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SharedSessionContractImplementor session) {
final int span = entityMetamodel.getPropertySpan(); final EntityPersister entityDescriptor = resolveEntityDescriptor();
final Object[] result = new Object[span]; return entityDescriptor.getPropertyValuesToInsert( entity, mergeMap, session );
for ( int j = 0; j < span; j++ ) {
result[j] = getters[j].getForInsert( entity, mergeMap, session );
}
return result;
} }
@Override @Override
public Object getPropertyValue(Object entity, int i) throws HibernateException { public Object getPropertyValue(Object entity, int i) throws HibernateException {
return getters[i].get( entity ); final EntityPersister entityDescriptor = resolveEntityDescriptor();
return entityDescriptor.getPropertyValue( entity, i );
} }
/** /**
@ -533,18 +212,6 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
throw new MappingException( "component property not found: " + subPropertyName ); throw new MappingException( "component property not found: " + subPropertyName );
} }
protected void linkToSession(Object entity, SharedSessionContractImplementor session) {
if ( session == null ) {
return;
}
if ( entity instanceof PersistentAttributeInterceptable ) {
final BytecodeLazyAttributeInterceptor interceptor = getEntityMetamodel().getBytecodeEnhancementMetadata().extractLazyInterceptor( entity );
if ( interceptor != null ) {
interceptor.setSession( session );
}
}
}
protected final EntityMetamodel getEntityMetamodel() { protected final EntityMetamodel getEntityMetamodel() {
return entityMetamodel; return entityMetamodel;
} }
@ -553,10 +220,6 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
return entityMetamodel.getSessionFactory(); return entityMetamodel.getSessionFactory();
} }
protected final Instantiator getInstantiator() {
return instantiator;
}
@Override @Override
public String toString() { public String toString() {
return getClass().getName() + '(' + getEntityMetamodel().getName() + ')'; return getClass().getName() + '(' + getEntityMetamodel().getName() + ')';

View File

@ -22,7 +22,6 @@ import org.hibernate.property.access.spi.Setter;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
import org.hibernate.proxy.map.MapProxyFactory; import org.hibernate.proxy.map.MapProxyFactory;
import org.hibernate.tuple.DynamicMapInstantiator; import org.hibernate.tuple.DynamicMapInstantiator;
import org.hibernate.tuple.Instantiator;
/** /**
* An {@link EntityTuplizer} specific to the dynamic-map entity mode. * An {@link EntityTuplizer} specific to the dynamic-map entity mode.
@ -56,11 +55,6 @@ public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
return buildPropertyAccess( mappedProperty ).getSetter(); return buildPropertyAccess( mappedProperty ).getSetter();
} }
@Override
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) {
return new DynamicMapInstantiator( mappingInfo );
}
@Override @Override
protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) { protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {

View File

@ -37,7 +37,12 @@ public interface EntityTuplizer extends Tuplizer {
* @param session The session from which is requests originates * @param session The session from which is requests originates
* *
* @return The identifier value. * @return The identifier value.
*
* @deprecated (as of 6.0) - no longer used internally and to be removed.
* Use {@link org.hibernate.metamodel.mapping.EntityIdentifierMapping#getIdentifier}
* instead
*/ */
@Deprecated
Object getIdentifier(Object entity, SharedSessionContractImplementor session); Object getIdentifier(Object entity, SharedSessionContractImplementor session);
/** /**

View File

@ -1,64 +0,0 @@
/*
* 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.tuple.entity;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.tuple.PojoInstantiator;
/**
* @author Steve Ebersole
*/
public class PojoEntityInstantiator extends PojoInstantiator {
private final EntityMetamodel entityMetamodel;
private final Class proxyInterface;
private final boolean applyBytecodeInterception;
public PojoEntityInstantiator(
EntityMetamodel entityMetamodel,
PersistentClass persistentClass,
ReflectionOptimizer.InstantiationOptimizer optimizer) {
super(
persistentClass.getMappedClass(),
optimizer,
persistentClass.hasEmbeddedIdentifier()
);
this.entityMetamodel = entityMetamodel;
this.proxyInterface = persistentClass.getProxyInterface();
this.applyBytecodeInterception = PersistentAttributeInterceptable.class.isAssignableFrom( persistentClass.getMappedClass() );
}
@Override
protected Object applyInterception(Object entity) {
if ( !applyBytecodeInterception ) {
return entity;
}
PersistentAttributeInterceptor interceptor = new LazyAttributeLoadingInterceptor(
entityMetamodel.getName(),
null,
entityMetamodel.getBytecodeEnhancementMetadata()
.getLazyAttributesMetadata()
.getLazyAttributeNames(),
null
);
( (PersistentAttributeInterceptable) entity ).$$_hibernate_setInterceptor( interceptor );
return entity;
}
@Override
public boolean isInstance(Object object) {
return super.isInstance( object ) ||
//this one needed only for guessEntityMode()
( proxyInterface!=null && proxyInterface.isInstance(object) );
}
}

View File

@ -120,16 +120,6 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
return proxyFactory.buildProxyFactory( getFactory() ); return proxyFactory.buildProxyFactory( getFactory() );
} }
@Override
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
if ( optimizer == null ) {
return new PojoEntityInstantiator( entityMetamodel, persistentClass, null );
}
else {
return new PojoEntityInstantiator( entityMetamodel, persistentClass, optimizer.getInstantiationOptimizer() );
}
}
@Override @Override
public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SharedSessionContractImplementor session) { public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SharedSessionContractImplementor session) {
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) { if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {

View File

@ -9,7 +9,6 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.PojoEntityTuplizer; import org.hibernate.tuple.entity.PojoEntityTuplizer;
@ -22,11 +21,6 @@ public class MyEntityTuplizer extends PojoEntityTuplizer {
super( entityMetamodel, mappedEntity ); super( entityMetamodel, mappedEntity );
} }
@Override
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
return new MyEntityInstantiator( persistentClass.getEntityName() );
}
@Override @Override
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) { protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
// allows defining a custom proxy factory, which is responsible for // allows defining a custom proxy factory, which is responsible for

View File

@ -12,8 +12,7 @@ import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
import org.hibernate.test.dynamicentity.ProxyHelper; import org.hibernate.test.dynamicentity.ProxyHelper;
import org.hibernate.test.dynamicentity.tuplizer.MyEntityInstantiator;
import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.entity.PojoEntityTuplizer; import org.hibernate.tuple.entity.PojoEntityTuplizer;
@ -31,11 +30,6 @@ public class MyEntityTuplizer extends PojoEntityTuplizer {
return new EntityNameResolver[] { MyEntityNameResolver.INSTANCE }; return new EntityNameResolver[] { MyEntityNameResolver.INSTANCE };
} }
@Override
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
return new MyEntityInstantiator( persistentClass.getEntityName() );
}
@Override @Override
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) { public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
String entityName = ProxyHelper.extractEntityName( entityInstance ); String entityName = ProxyHelper.extractEntityName( entityInstance );