org.hibernate.tuple.entity.PojoEntityTuplizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
JPMS Module-Info's for a few of the Jakarta Libraries just until they add them in themselves
/*
* 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 .
*/
package org.hibernate.tuple.entity;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import org.hibernate.EntityMode;
import org.hibernate.EntityNameResolver;
import org.hibernate.HibernateException;
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.bytecode.spi.ProxyFactoryFactory;
import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.cfg.Environment;
import org.hibernate.classic.Lifecycle;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.SelfDirtinessTracker;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.Setter;
import org.hibernate.proxy.ProxyFactory;
import org.hibernate.proxy.pojo.ProxyFactoryHelper;
import org.hibernate.tuple.Instantiator;
import org.hibernate.type.CompositeType;
/**
* An {@link EntityTuplizer} specific to the pojo entity mode.
*
* @author Steve Ebersole
* @author Gavin King
*/
public class PojoEntityTuplizer extends AbstractEntityTuplizer {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoEntityTuplizer.class );
private final Class mappedClass;
private final Class proxyInterface;
private final boolean lifecycleImplementor;
private final ReflectionOptimizer optimizer;
public PojoEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
super( entityMetamodel, mappedEntity );
this.mappedClass = mappedEntity.getMappedClass();
this.proxyInterface = mappedEntity.getProxyInterface();
this.lifecycleImplementor = Lifecycle.class.isAssignableFrom( mappedClass );
String[] getterNames = new String[propertySpan];
String[] setterNames = new String[propertySpan];
Class[] propTypes = new Class[propertySpan];
for ( int i = 0; i < propertySpan; i++ ) {
getterNames[i] = getters[i].getMethodName();
setterNames[i] = setters[i].getMethodName();
propTypes[i] = getters[i].getReturnType();
}
if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {
optimizer = null;
}
else {
final BytecodeProvider bytecodeProvider = entityMetamodel.getSessionFactory().getServiceRegistry().getService( BytecodeProvider.class );
optimizer = bytecodeProvider.getReflectionOptimizer(
mappedClass,
getterNames,
setterNames,
propTypes
);
}
}
@Override
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
// determine the id getter and setter methods from the proxy interface (if any)
// determine all interfaces needed by the resulting proxy
final String entityName = getEntityName();
final Class mappedClass = persistentClass.getMappedClass();
final Class proxyInterface = persistentClass.getProxyInterface();
final Set proxyInterfaces = ProxyFactoryHelper.extractProxyInterfaces( persistentClass, entityName );
Method proxyGetIdentifierMethod = ProxyFactoryHelper.extractProxyGetIdentifierMethod( idGetter, proxyInterface );
Method proxySetIdentifierMethod = ProxyFactoryHelper.extractProxySetIdentifierMethod( idSetter, proxyInterface );
ProxyFactory pf = buildProxyFactoryInternal( persistentClass, idGetter, idSetter );
try {
ProxyFactoryHelper.validateGetterSetterMethodProxyability( "Getter", proxyGetIdentifierMethod );
ProxyFactoryHelper.validateGetterSetterMethodProxyability( "Setter", proxySetIdentifierMethod );
ProxyFactoryHelper.validateProxyability( persistentClass );
pf.postInstantiate(
entityName,
mappedClass,
proxyInterfaces,
proxyGetIdentifierMethod,
proxySetIdentifierMethod,
persistentClass.hasEmbeddedIdentifier() ?
(CompositeType) persistentClass.getIdentifier().getType() :
null
);
}
catch (HibernateException he) {
LOG.unableToCreateProxyFactory( entityName, he );
pf = null;
}
return pf;
}
protected ProxyFactory buildProxyFactoryInternal(
PersistentClass persistentClass,
Getter idGetter,
Setter idSetter) {
ProxyFactoryFactory proxyFactory = getFactory().getServiceRegistry().getService( ProxyFactoryFactory.class );
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
public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
if ( !getEntityMetamodel().hasLazyProperties() && optimizer != null && optimizer.getAccessOptimizer() != null ) {
setPropertyValuesWithOptimizer( entity, values );
}
else {
super.setPropertyValues( entity, values );
}
}
@Override
public Object[] getPropertyValues(Object entity) throws HibernateException {
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
return getPropertyValuesWithOptimizer( entity );
}
else {
return super.getPropertyValues( entity );
}
}
@Override
public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SharedSessionContractImplementor session) {
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
return getPropertyValuesWithOptimizer( entity );
}
else {
return super.getPropertyValuesToInsert( entity, mergeMap, session );
}
}
protected void setPropertyValuesWithOptimizer(Object object, Object[] values) {
optimizer.getAccessOptimizer().setPropertyValues( object, values );
}
protected Object[] getPropertyValuesWithOptimizer(Object object) {
return optimizer.getAccessOptimizer().getPropertyValues( object );
}
@Override
public EntityMode getEntityMode() {
return EntityMode.POJO;
}
@Override
public Class getMappedClass() {
return mappedClass;
}
@Override
public boolean isLifecycleImplementor() {
return lifecycleImplementor;
}
@Override
protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
return mappedProperty.getGetter( mappedEntity.getMappedClass() );
}
@Override
protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
return mappedProperty.getSetter( mappedEntity.getMappedClass() );
}
@Override
public Class getConcreteProxyClass() {
return proxyInterface;
}
//TODO: need to make the majority of this functionality into a top-level support class for custom impl support
@Override
public void afterInitialize(Object entity, SharedSessionContractImplementor session) {
if ( entity instanceof PersistentAttributeInterceptable ) {
final BytecodeLazyAttributeInterceptor interceptor = getEntityMetamodel().getBytecodeEnhancementMetadata().extractLazyInterceptor( entity );
if ( interceptor == null || interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
getEntityMetamodel().getBytecodeEnhancementMetadata().injectInterceptor(
entity,
getIdentifier( entity, session ),
session
);
}
else {
if ( interceptor.getLinkedSession() == null ) {
interceptor.setSession( session );
}
}
}
// clear the fields that are marked as dirty in the dirtiness tracker
if ( entity instanceof SelfDirtinessTracker ) {
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
}
}
@Override
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
if ( entityInstance == null ) {
return getEntityName();
}
final Class concreteEntityClass = entityInstance.getClass();
if ( concreteEntityClass == getMappedClass() ) {
return getEntityName();
}
else {
String entityName = getEntityMetamodel().findEntityNameByEntityClass( concreteEntityClass );
if ( entityName == null ) {
throw new HibernateException(
"Unable to resolve entity name from Class [" + concreteEntityClass.getName() + "]"
+ " expected instance/subclass of [" + getEntityName() + "]"
);
}
return entityName;
}
}
@Override
public EntityNameResolver[] getEntityNameResolvers() {
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy