org.hibernate.tuple.entity.BytecodeEnhancementMetadataPojoImpl Maven / Gradle / Ivy
/*
* 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.io.Serializable;
import java.util.Set;
import org.hibernate.LockMode;
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributesMetadata;
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
import org.hibernate.bytecode.spi.NotInstrumentedException;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SelfDirtinessTracker;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.type.CompositeType;
/**
* @author Steve Ebersole
*/
public final class BytecodeEnhancementMetadataPojoImpl implements BytecodeEnhancementMetadata {
/**
* Static constructor
*/
public static BytecodeEnhancementMetadata from(
PersistentClass persistentClass,
Set identifierAttributeNames,
CompositeType nonAggregatedCidMapper,
boolean collectionsInDefaultFetchGroupEnabled,
PersisterCreationContext creationContext) {
final Class mappedClass = persistentClass.getMappedClass();
final boolean enhancedForLazyLoading = PersistentAttributeInterceptable.class.isAssignableFrom( mappedClass );
final LazyAttributesMetadata lazyAttributesMetadata = enhancedForLazyLoading
? LazyAttributesMetadata.from( persistentClass, true, collectionsInDefaultFetchGroupEnabled, creationContext )
: LazyAttributesMetadata.nonEnhanced( persistentClass.getEntityName() );
return new BytecodeEnhancementMetadataPojoImpl(
persistentClass.getEntityName(),
mappedClass,
identifierAttributeNames,
nonAggregatedCidMapper,
enhancedForLazyLoading,
lazyAttributesMetadata
);
}
private final String entityName;
private final Class entityClass;
private final Set identifierAttributeNames;
private final CompositeType nonAggregatedCidMapper;
private final boolean enhancedForLazyLoading;
private final LazyAttributesMetadata lazyAttributesMetadata;
@SuppressWarnings("WeakerAccess")
protected BytecodeEnhancementMetadataPojoImpl(
String entityName,
Class entityClass,
Set identifierAttributeNames,
CompositeType nonAggregatedCidMapper,
boolean enhancedForLazyLoading,
LazyAttributesMetadata lazyAttributesMetadata) {
this.nonAggregatedCidMapper = nonAggregatedCidMapper;
assert identifierAttributeNames != null;
assert !identifierAttributeNames.isEmpty();
this.entityName = entityName;
this.entityClass = entityClass;
this.identifierAttributeNames = identifierAttributeNames;
this.enhancedForLazyLoading = enhancedForLazyLoading;
this.lazyAttributesMetadata = lazyAttributesMetadata;
}
@Override
public String getEntityName() {
return entityName;
}
@Override
public boolean isEnhancedForLazyLoading() {
return enhancedForLazyLoading;
}
@Override
public LazyAttributesMetadata getLazyAttributesMetadata() {
return lazyAttributesMetadata;
}
@Override
public boolean hasUnFetchedAttributes(Object entity) {
if ( ! enhancedForLazyLoading ) {
return false;
}
final BytecodeLazyAttributeInterceptor interceptor = extractLazyInterceptor( entity );
if ( interceptor instanceof LazyAttributeLoadingInterceptor ) {
return ( (LazyAttributeLoadingInterceptor) interceptor ).hasAnyUninitializedAttributes();
}
//noinspection RedundantIfStatement
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
return true;
}
return false;
}
@Override
public boolean isAttributeLoaded(Object entity, String attributeName) {
if ( ! enhancedForLazyLoading ) {
return true;
}
final BytecodeLazyAttributeInterceptor interceptor = extractLazyInterceptor( entity );
if ( interceptor instanceof LazyAttributeLoadingInterceptor ) {
return ( (LazyAttributeLoadingInterceptor) interceptor ).isAttributeLoaded( attributeName );
}
return true;
}
@Override
public LazyAttributeLoadingInterceptor extractInterceptor(Object entity) throws NotInstrumentedException {
return (LazyAttributeLoadingInterceptor) extractLazyInterceptor( entity );
}
@Override
public PersistentAttributeInterceptable createEnhancedProxy(EntityKey entityKey, boolean addEmptyEntry, SharedSessionContractImplementor session) {
final EntityPersister persister = entityKey.getPersister();
final Serializable identifier = entityKey.getIdentifier();
final PersistenceContext persistenceContext = session.getPersistenceContext();
// first, instantiate the entity instance to use as the proxy
final EntityTuplizer entityTuplizer = persister.getEntityTuplizer();
final PersistentAttributeInterceptable entity = (PersistentAttributeInterceptable) entityTuplizer
.instantiate( identifier, session );
// clear the fields that are marked as dirty in the dirtiness tracker
if ( entity instanceof SelfDirtinessTracker ) {
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
}
// add the entity (proxy) instance to the PC
persistenceContext.addEnhancedProxy( entityKey, entity );
// if requested, add the "holder entry" to the PC
if ( addEmptyEntry ) {
persistenceContext.addEntry(
entity,
Status.MANAGED,
// loaded state
null,
// row-id
null,
identifier,
// version
null,
LockMode.NONE,
// we assume it exists in db
true,
persister,
true
);
}
// inject the interceptor
persister.getEntityMetamodel()
.getBytecodeEnhancementMetadata()
.injectEnhancedEntityAsProxyInterceptor( entity, entityKey, session );
return entity;
}
@Override
public LazyAttributeLoadingInterceptor injectInterceptor(
Object entity,
Object identifier,
SharedSessionContractImplementor session) {
if ( !enhancedForLazyLoading ) {
throw new NotInstrumentedException( "Entity class [" + entityClass.getName() + "] is not enhanced for lazy loading" );
}
if ( !entityClass.isInstance( entity ) ) {
throw new IllegalArgumentException(
String.format(
"Passed entity instance [%s] is not of expected type [%s]",
entity,
getEntityName()
)
);
}
final LazyAttributeLoadingInterceptor interceptor = new LazyAttributeLoadingInterceptor(
getEntityName(),
identifier,
lazyAttributesMetadata.getLazyAttributeNames(),
session
);
injectInterceptor( entity, interceptor, session );
return interceptor;
}
@Override
public void injectEnhancedEntityAsProxyInterceptor(
Object entity,
EntityKey entityKey,
SharedSessionContractImplementor session) {
injectInterceptor(
entity,
new EnhancementAsProxyLazinessInterceptor(
entityName,
identifierAttributeNames,
nonAggregatedCidMapper,
entityKey,
session
),
session
);
}
@Override
public void injectInterceptor(
Object entity,
PersistentAttributeInterceptor interceptor,
SharedSessionContractImplementor session) {
if ( !enhancedForLazyLoading ) {
throw new NotInstrumentedException( "Entity class [" + entityClass.getName() + "] is not enhanced for lazy loading" );
}
if ( !entityClass.isInstance( entity ) ) {
throw new IllegalArgumentException(
String.format(
"Passed entity instance [%s] is not of expected type [%s]",
entity,
getEntityName()
)
);
}
( (PersistentAttributeInterceptable) entity ).$$_hibernate_setInterceptor( interceptor );
}
@Override
public BytecodeLazyAttributeInterceptor extractLazyInterceptor(Object entity) throws NotInstrumentedException {
if ( !enhancedForLazyLoading ) {
throw new NotInstrumentedException( "Entity class [" + entityClass.getName() + "] is not enhanced for lazy loading" );
}
if ( !entityClass.isInstance( entity ) ) {
throw new IllegalArgumentException(
String.format(
"Passed entity instance [%s] is not of expected type [%s]",
entity,
getEntityName()
)
);
}
final PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
if ( interceptor == null ) {
return null;
}
return (BytecodeLazyAttributeInterceptor) interceptor;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy