HHH-8647 - hibernate.cache.use_reference_entries + queries

Conflicts:
	hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java
This commit is contained in:
Steve Ebersole 2013-10-29 06:13:25 -04:00 committed by Brett Meyer
parent 70b9644ca4
commit 4b543dc552
7 changed files with 54 additions and 5 deletions

View File

@ -54,6 +54,8 @@ import org.hibernate.WrongClassException;
import org.hibernate.cache.spi.FilterKey;
import org.hibernate.cache.spi.QueryCache;
import org.hibernate.cache.spi.QueryKey;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.pagination.LimitHandler;
@ -114,8 +116,11 @@ public abstract class Loader {
private final SessionFactoryImplementor factory;
private ColumnNameCache columnNameCache;
private final boolean referenceCachingEnabled;
public Loader(SessionFactoryImplementor factory) {
this.factory = factory;
this.referenceCachingEnabled = factory.getSettings().isDirectReferenceCacheEntriesEnabled();
}
/**
@ -1563,6 +1568,7 @@ public abstract class Loader {
}
}
/**
* The entity instance is not in the session cache
*/
@ -1586,6 +1592,22 @@ public abstract class Loader {
session
);
// see if the entity defines reference caching, and if so use the cached reference (if one).
if ( persister.canUseReferenceCacheEntries() ) {
final Object cachedEntry = persister.getCacheAccessStrategy().get(
session.generateCacheKey(
key.getIdentifier(),
persister.getEntityMetamodel().getEntityType(),
key.getEntityName()
),
session.getTimestamp()
);
if ( cachedEntry != null ) {
CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( cachedEntry, factory );
return ( (ReferenceCacheEntryImpl) entry ).getReference();
}
}
final Object object;
if ( optionalObjectKey != null && key.equals( optionalObjectKey ) ) {
//its the given optional object

View File

@ -798,7 +798,7 @@ public abstract class AbstractEntityPersister
: new StandardCacheEntryHelper( this );
}
protected boolean canUseReferenceCacheEntries() {
public boolean canUseReferenceCacheEntries() {
// todo : should really validate that the cache access type is read-only
if ( ! factory.getSettings().isDirectReferenceCacheEntriesEnabled() ) {

View File

@ -759,4 +759,5 @@ public interface EntityPersister extends OptimisticCacheSource {
public int[] resolveAttributeIndexes(Set<String> properties);
public boolean canUseReferenceCacheEntries();
}

View File

@ -31,6 +31,7 @@ import org.hibernate.Session;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Proxy;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.persister.entity.EntityPersister;
@ -50,6 +51,7 @@ public class ReferenceCacheTest extends BaseCoreFunctionalTestCase {
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( AvailableSettings.USE_DIRECT_REFERENCE_CACHE_ENTRIES, "true" );
configuration.setProperty( AvailableSettings.USE_QUERY_CACHE, "true" );
}
@Override
@ -84,6 +86,16 @@ public class ReferenceCacheTest extends BaseCoreFunctionalTestCase {
// the 2 instances should be the same (==)
assertTrue( "The two instances were different references", myReferenceData == loaded );
// now try query caching
s = openSession();
s.beginTransaction();
MyReferenceData queried = (MyReferenceData) s.createQuery( "from MyReferenceData" ).setCacheable( true ).list().get( 0 );
s.getTransaction().commit();
s.close();
// the 2 instances should be the same (==)
assertTrue( "The two instances were different references", myReferenceData == queried );
// cleanup
s = openSession();
s.beginTransaction();
@ -96,7 +108,7 @@ public class ReferenceCacheTest extends BaseCoreFunctionalTestCase {
@Immutable
@Cacheable
@Cache( usage = CacheConcurrencyStrategy.READ_ONLY )
// @Proxy( lazy = false )
@Proxy( lazy = false )
@SuppressWarnings("UnusedDeclaration")
public static class MyReferenceData {
@Id

View File

@ -585,6 +585,11 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
public int[] resolveAttributeIndexes(Set<String> attributes) {
return null;
}
@Override
public boolean canUseReferenceCacheEntries() {
return false;
}
}
public static class NoopCollectionPersister implements CollectionPersister {

View File

@ -677,4 +677,9 @@ public class CustomPersister implements EntityPersister {
public int[] resolveAttributeIndexes(Set<String> attributes) {
return null;
}
@Override
public boolean canUseReferenceCacheEntries() {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
}

View File

@ -28,9 +28,6 @@ import java.util.Set;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
@ -63,6 +60,8 @@ import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.tuple.entity.NonPojoInstrumentationMetadata;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Emmanuel Bernard <emmanuel@hibernate.org>
@ -149,6 +148,11 @@ public class PersisterClassProviderTest {
return null;
}
@Override
public boolean canUseReferenceCacheEntries() {
return false;
}
@Override
public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) {
return null;