FileDocCategorySizeDatePackage
StandardQueryCache.javaAPI DocHibernate 3.2.54994Thu Jul 13 16:38:42 BST 2006org.hibernate.cache

StandardQueryCache

public class StandardQueryCache extends Object implements QueryCache
The standard implementation of the Hibernate QueryCache interface. This implementation is very good at recognizing stale query results and and re-running queries when it detects this condition, recaching the new results.
author
Gavin King

Fields Summary
private static final Log
log
private Cache
queryCache
private UpdateTimestampsCache
updateTimestampsCache
private final String
regionName
Constructors Summary
public StandardQueryCache(org.hibernate.cfg.Settings settings, Properties props, UpdateTimestampsCache updateTimestampsCache, String regionName)

		if ( regionName == null ) {
			regionName = StandardQueryCache.class.getName();
		}
		String prefix = settings.getCacheRegionPrefix();
		if ( prefix != null ) {
			regionName = prefix + '." + regionName;
		}
		log.info( "starting query cache at region: " + regionName );

		this.queryCache = settings.getCacheProvider().buildCache(regionName, props);
		this.updateTimestampsCache = updateTimestampsCache;
		this.regionName = regionName;
	
Methods Summary
public voidclear()


	     
		queryCache.clear();
	
public voiddestroy()

		try {
			queryCache.destroy();
		}
		catch (Exception e) {
			log.warn("could not destroy query cache: " + regionName, e);
		}
	
public java.util.Listget(QueryKey key, org.hibernate.type.Type[] returnTypes, boolean isNaturalKeyLookup, java.util.Set spaces, org.hibernate.engine.SessionImplementor session)

		if ( log.isDebugEnabled() ) {
			log.debug("checking cached query results in region: " + regionName);
		}

		List cacheable = (List) queryCache.get(key);
		if (cacheable==null) {
			log.debug("query results were not found in cache");
			return null;
		}

		Long timestamp = (Long) cacheable.get(0);
		if ( !isNaturalKeyLookup && !isUpToDate(spaces, timestamp) ) {
			log.debug("cached query results were not up to date");
			return null;
		}

		log.debug("returning cached query results");
		for ( int i=1; i<cacheable.size(); i++ ) {
			if ( returnTypes.length==1 ) {
				returnTypes[0].beforeAssemble( (Serializable) cacheable.get(i), session );
			}
			else {
				TypeFactory.beforeAssemble( (Serializable[]) cacheable.get(i), returnTypes, session );
			}
		}
		List result = new ArrayList( cacheable.size()-1 );
		for ( int i=1; i<cacheable.size(); i++ ) {
			try {
				if ( returnTypes.length==1 ) {
					result.add( returnTypes[0].assemble( (Serializable) cacheable.get(i), session, null ) );
				}
				else {
					result.add( TypeFactory.assemble( (Serializable[]) cacheable.get(i), returnTypes, session, null ) );
				}
			}
			catch (UnresolvableObjectException uoe) {
				if (isNaturalKeyLookup) {
					//TODO: not really completely correct, since
					//      the uoe could occur while resolving
					//      associations, leaving the PC in an
					//      inconsistent state
					log.debug("could not reassemble cached result set");
					queryCache.remove(key);
					return null;
				}
				else {
					throw uoe;
				}
			}
		}
		return result;
	
public CachegetCache()

		return queryCache;
	
public java.lang.StringgetRegionName()

		return regionName;
	
protected booleanisUpToDate(java.util.Set spaces, java.lang.Long timestamp)

		if ( log.isDebugEnabled() ) {
			log.debug("Checking query spaces for up-to-dateness: " + spaces);
		}
		return updateTimestampsCache.isUpToDate(spaces, timestamp);
	
public booleanput(QueryKey key, org.hibernate.type.Type[] returnTypes, java.util.List result, boolean isNaturalKeyLookup, org.hibernate.engine.SessionImplementor session)

		
		if ( isNaturalKeyLookup && result.size()==0 ) {
			return false;
		}
		else {
			Long ts = new Long( session.getTimestamp() );

			if ( log.isDebugEnabled() ) {
				log.debug( "caching query results in region: " + regionName + "; timestamp=" + ts );
			}
			
			List cacheable = new ArrayList( result.size()+1 );
			cacheable.add( ts );
			for ( int i=0; i<result.size(); i++ ) {
				if ( returnTypes.length==1 ) {
					cacheable.add( returnTypes[0].disassemble( result.get(i), session, null ) );
				}
				else {
					cacheable.add( TypeFactory.disassemble( (Object[]) result.get(i), returnTypes, null, session, null ) );
				}
			}
			
			queryCache.put(key, cacheable);
			
			return true;
			
		}

	
public java.lang.StringtoString()

		return "StandardQueryCache(" + regionName + ')";