HHH-8991 Cache lookup of identifier Type and associated EntityPersister for each EntityType

This commit is contained in:
Sanne Grinovero 2014-02-22 00:02:30 +00:00
parent 586f9c2a55
commit f0bf53e40e
2 changed files with 57 additions and 14 deletions

View File

@ -64,6 +64,19 @@ public abstract class EntityType extends AbstractType implements AssociationType
private final boolean unwrapProxy;
private final boolean referenceToPrimaryKey;
/**
* Cached because of performance
* @see #getIdentifierType(SessionImplementor)
* @see #getIdentifierType(Mapping)
*/
private transient volatile Type associatedIdentifierType;
/**
* Cached because of performance
* @see #getAssociatedEntityPersister
*/
private transient volatile EntityPersister associatedEntityPersister;
private transient Class returnedClass;
/**
@ -248,7 +261,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
*/
@Override
public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException {
return ( Joinable ) factory.getEntityPersister( associatedEntityName );
return ( Joinable ) getAssociatedEntityPersister( factory );
}
/**
@ -357,7 +370,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
@Override
public int getHashCode(Object x, SessionFactoryImplementor factory) {
EntityPersister persister = factory.getEntityPersister(associatedEntityName);
EntityPersister persister = getAssociatedEntityPersister( factory );
if ( !persister.canExtractIdOutOfEntity() ) {
return super.getHashCode( x );
}
@ -385,7 +398,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
return x == y;
}
EntityPersister persister = factory.getEntityPersister(associatedEntityName);
EntityPersister persister = getAssociatedEntityPersister( factory );
if ( !persister.canExtractIdOutOfEntity() ) {
return super.isEqual(x, y );
}
@ -498,7 +511,21 @@ public abstract class EntityType extends AbstractType implements AssociationType
@Override
public Type getSemiResolvedType(SessionFactoryImplementor factory) {
return factory.getEntityPersister( associatedEntityName ).getIdentifierType();
return getAssociatedEntityPersister( factory ).getIdentifierType();
}
protected EntityPersister getAssociatedEntityPersister(final SessionFactoryImplementor factory) {
final EntityPersister persister = associatedEntityPersister;
//The following branch implements a simple lazy-initialization, but rather than the canonical
//form it returns the local variable to avoid a second volatile read: associatedEntityPersister
//needs to be volatile as the initialization might happen by a different thread than the readers.
if ( persister == null ) {
associatedEntityPersister = factory.getEntityPersister( getAssociatedEntityName() );
return associatedEntityPersister;
}
else {
return persister;
}
}
protected final Object getIdentifier(Object value, SessionImplementor session) throws HibernateException {
@ -513,7 +540,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
return null;
}
else {
EntityPersister entityPersister = session.getFactory().getEntityPersister( getAssociatedEntityName() );
EntityPersister entityPersister = getAssociatedEntityPersister( session.getFactory() );
Object propertyValue = entityPersister.getPropertyValue( value, uniqueKeyPropertyName );
// We now have the value of the property-ref we reference. However,
// we need to dig a little deeper, as that property might also be
@ -551,7 +578,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
return "null";
}
EntityPersister persister = factory.getEntityPersister( associatedEntityName );
EntityPersister persister = getAssociatedEntityPersister( factory );
StringBuilder result = new StringBuilder().append( associatedEntityName );
if ( persister.hasIdentifierProperty() ) {
@ -599,8 +626,18 @@ public abstract class EntityType extends AbstractType implements AssociationType
* @param factory The mappings...
* @return The identifier type
*/
Type getIdentifierType(Mapping factory) {
return factory.getIdentifierType( getAssociatedEntityName() );
Type getIdentifierType(final Mapping factory) {
final Type type = associatedIdentifierType;
//The following branch implements a simple lazy-initialization, but rather than the canonical
//form it returns the local variable to avoid a second volatile read: associatedIdentifierType
//needs to be volatile as the initialization might happen by a different thread than the readers.
if ( type == null ) {
associatedIdentifierType = factory.getIdentifierType( getAssociatedEntityName() );
return associatedIdentifierType;
}
else {
return type;
}
}
/**
@ -609,8 +646,15 @@ public abstract class EntityType extends AbstractType implements AssociationType
* @param session The originating session
* @return The identifier type
*/
Type getIdentifierType(SessionImplementor session) {
return getIdentifierType( session.getFactory() );
Type getIdentifierType(final SessionImplementor session) {
final Type type = associatedIdentifierType;
if ( type == null ) {
associatedIdentifierType = getIdentifierType( session.getFactory() );
return associatedIdentifierType;
}
else {
return type;
}
}
/**
@ -666,8 +710,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
*/
protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException {
boolean isProxyUnwrapEnabled = unwrapProxy &&
session.getFactory()
.getEntityPersister( getAssociatedEntityName() )
getAssociatedEntityPersister( session.getFactory() )
.isInstrumented();
Object proxyOrEntity = session.internalLoad(

View File

@ -200,7 +200,7 @@ public class ManyToOneType extends EntityType {
private void scheduleBatchLoadIfNeeded(Serializable id, SessionImplementor session) throws MappingException {
//cannot batch fetch by unique key (property-ref associations)
if ( uniqueKeyPropertyName == null && id != null ) {
final EntityPersister persister = session.getFactory().getEntityPersister( getAssociatedEntityName() );
final EntityPersister persister = getAssociatedEntityPersister( session.getFactory() );
if ( persister.isBatchLoadable() ) {
final EntityKey entityKey = session.generateEntityKey( id, persister );
if ( !session.getPersistenceContext().containsEntity( entityKey ) ) {
@ -209,7 +209,7 @@ public class ManyToOneType extends EntityType {
}
}
}
public boolean useLHSPrimaryKey() {
return false;
}