david wrote:
Hibernate 2.1 has query based caching so your find results will be cached.
So what does this do? From my quick test, it looks like this data is grabbed from the database every time. Here is all the info you may need. Keep in mind that this is my first stab at caching in Hibernate (and I find the JCS docs to be "unhelpful" and I am going straight from the JCS example in the Hibernate wiki).
cache.ccf
Code:
# DEFAULT CACHE REGION (memory cache)
jcs.default=DC
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=2000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.default.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.default.elementattributes.IsEternal=false
jcs.default.elementattributes.MaxLifeSeconds=24000
jcs.default.elementattributes.IdleTime=180000
jcs.default.elementattributes.IsSpool=false
jcs.default.elementattributes.IsRemote=false
jcs.default.elementattributes.IsLateral=false
#ContainerType Cache
jcs.region.com.mycompany.rts.tips.ContainerType=DC
jcs.region.com.mycompany.rts.tips.ContainerType.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.region.com.mycompany.rts.tips.ContainerType.cacheattributes.MaxObjects=1000
jcs.region.com.mycompany.rts.tips.ContainerType.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.region.com.mycompany.rts.tips.ContainerType.cacheattributes.UseMemoryShrinker=true
jcs.region.com.mycompany.rts.tips.ContainerType.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.region.com.mycompany.rts.tips.ContainerType.cacheattributes.ShrinkerIntervalSeconds=60
jcs.region.com.mycompany.rts.tips.ContainerType.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.region.com.mycompany.rts.tips.ContainerType.elementattributes.IsEternal=false
jcs.region.com.mycompany.rts.tips.ContainerType.elementattributes.MaxLifeSeconds=240
jcs.region.com.mycompany.rts.tips.ContainerType.elementattributes.IdleTime=180
jcs.region.com.mycompany.rts.tips.ContainerType.elementattributes.IsSpool=false
jcs.region.com.mycompany.rts.tips.ContainerType.elementattributes.IsRemote=false
jcs.region.com.mycompany.rts.tips.ContainerType.elementattributes.IsLateral=false
AbstractTipsConstant .java
Code:
import java.io.Serializable;
public abstract class AbstractTipsConstant implements Serializable {
private String description;
private String status;
/**
* @hibernate.property
* column="freight_class_description"
*/
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/**
* @hibernate.property
*/
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
ContainerType.java
Code:
/**
* @hibernate.class
* table="tips_container_msi"
* mutable="false"
* schema="tips"
*
* @hibernate.jcs-cache
* usage="read-only"
*/
public class ContainerType extends AbstractTipsConstant {
private String type;
/**
* @hibernate.id
* column="container_type"
* generator-class="assigned"
*/
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
* @hibernate.property
* column="container_description"
*/
public String getDescription() {
return super.getDescription();
}
}
ContainerType.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="com.mycompany.rts.tips.ContainerType"
table="tips_container_msi"
schema="tips"
dynamic-update="false"
dynamic-insert="false"
mutable="false"
>
<jcs-cache usage="read-only" />
<id
name="type"
column="container_type"
type="java.lang.String"
>
<generator class="assigned">
</generator>
</id>
<property
name="description"
type="java.lang.String"
update="true"
insert="true"
column="container_description"
/>
<property
name="status"
type="java.lang.String"
update="true"
insert="true"
column="status"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-ContainerType.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
TipsServicesImpl.java (uses Spring Framework)
Code:
...
public List getAllActiveContainerTypes() {
final String queryString =
"from ContainerType containerType where containerType.status = ? ";
return getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(queryString);
query.setString(0, "ACTIVE");
query.setCacheable(true);
return query.list();
}
});
}
...
This is what I see in the log file the *second* time this query is executed:
Code:
[DEBUG] 09:08:44 JDBCTransaction.begin - begin
[DEBUG] 09:08:44 DriverManagerConnectionProvider.getConnection - total checked-out connections: 0
[DEBUG] 09:08:44 DriverManagerConnectionProvider.getConnection - using pooled JDBC connection, pool size: 0
[DEBUG] 09:08:44 SessionImpl.find - find: from ContainerType containerType where containerType.status = ?
[DEBUG] 09:08:44 QueryParameters.traceParameters - parameters: [ACTIVE]
[DEBUG] 09:08:44 QueryParameters.traceParameters - named parameters: {}
[DEBUG] 09:08:44 QueryTranslator.compile - compiling query
[DEBUG] 09:08:44 SessionImpl.flushEverything - flushing session
[DEBUG] 09:08:44 SessionImpl.flushEntities - Flushing entities and processing referenced collections
[DEBUG] 09:08:44 SessionImpl.flushCollections - Processing unreferenced collections
[DEBUG] 09:08:44 SessionImpl.flushCollections - Scheduling collection removes/(re)creates/updates
[DEBUG] 09:08:44 SessionImpl.flushEverything - Flushed: 0 insertions, 0 updates, 0 deletions to 0 objects
[DEBUG] 09:08:44 SessionImpl.flushEverything - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
[DEBUG] 09:08:44 SessionImpl.autoFlushIfRequired - Dont need to execute flush
[DEBUG] 09:08:44 QueryTranslator.logQuery - HQL: from com.mycompany.rts.tips.ContainerType containerType where cont
ype.status = ?
[DEBUG] 09:08:44 QueryTranslator.logQuery - SQL: select containe0_.container_type as container_type, containe0_.co
r_description as containe2_, containe0_.status as status from tips.tips_container_msi containe0_ where (containe0_
s=? )
[DEBUG] 09:08:44 BatcherImpl.logOpenPreparedStatement - about to open: 0 open PreparedStatements, 0 open ResultSet
[DEBUG] 09:08:44 BatcherImpl.getPreparedStatement - prepared statement get: select containe0_.container_type as co
r_type, containe0_.container_description as containe2_, containe0_.status as status from tips.tips_container_msi c
e0_ where (containe0_.status=? )
[DEBUG] 09:08:44 BatcherImpl.getPreparedStatement - preparing statement
[DEBUG] 09:08:44 StringType.nullSafeSet - binding 'ACTIVE' to parameter: 1
[DEBUG] 09:08:44 Loader.doResultSet - processing result set
[DEBUG] 09:08:44 StringType.nullSafeGet - returning 'PIECES' as column: container_type
[DEBUG] 09:08:44 Loader.getRow - result row: PIECES
[DEBUG] 09:08:44 Loader.loadFromResultSet - Initializing object from ResultSet: PIECES
[DEBUG] 09:08:44 Loader.hydrate - Hydrating entity: com.mycompany.rts.tips.ContainerType#PIECES
[DEBUG] 09:08:44 StringType.nullSafeGet - returning 'Pieces of merchandise' as column: containe2_
[DEBUG] 09:08:44 StringType.nullSafeGet - returning 'ACTIVE' as column: status
[DEBUG] 09:08:44 StringType.nullSafeGet - returning 'PALLETS' as column: container_type
[DEBUG] 09:08:44 Loader.getRow - result row: PALLETS
[DEBUG] 09:08:44 Loader.loadFromResultSet - Initializing object from ResultSet: PALLETS
[DEBUG] 09:08:44 Loader.hydrate - Hydrating entity: com.mycompany.rts.tips.ContainerType#PALLETS
[DEBUG] 09:08:44 StringType.nullSafeGet - returning 'Pallets of merchandise' as column: containe2_
[DEBUG] 09:08:44 StringType.nullSafeGet - returning 'ACTIVE' as column: status
[DEBUG] 09:08:44 Loader.doResultSet - done processing result set (2 rows)
[DEBUG] 09:08:44 BatcherImpl.logClosePreparedStatement - done closing: 0 open PreparedStatements, 0 open ResultSet
[DEBUG] 09:08:44 BatcherImpl.closePreparedStatement - closing statement
[DEBUG] 09:08:44 Loader.doResultSet - total objects hydrated: 2
[DEBUG] 09:08:44 SessionImpl.initializeEntity - resolving associations for [com.mycompany.rts.tips.ContainerType#PI
[DEBUG] 09:08:44 SessionImpl.initializeEntity - adding entity to process-level cache [com.mycompany.rts.tips.Contai
e#PIECES]
[DEBUG] 09:08:44 ReadOnlyCache.put - Caching: PIECES
[DEBUG] 09:08:44 SessionImpl.initializeEntity - done materializing entity [com.mycompany.rts.tips.ContainerType#PIE
[DEBUG] 09:08:44 SessionImpl.initializeEntity - resolving associations for [com.mycompany.rts.tips.ContainerType#PA
[DEBUG] 09:08:44 SessionImpl.initializeEntity - adding entity to process-level cache [com.mycompany.rts.tips.Contai
e#PALLETS]
[DEBUG] 09:08:44 ReadOnlyCache.put - Caching: PALLETS
[DEBUG] 09:08:44 SessionImpl.initializeEntity - done materializing entity [com.mycompany.rts.tips.ContainerType#PAL
[DEBUG] 09:08:44 SessionImpl.initializeNonLazyCollections - initializing non-lazy collections
[ INFO] 09:08:44 TransactionInterceptor.invoke - Committing transaction on method 'getAllActiveContainerTypes'
[DEBUG] 09:08:44 SessionImpl.flushEverything - flushing session
[DEBUG] 09:08:44 SessionImpl.flushEntities - Flushing entities and processing referenced collections
[DEBUG] 09:08:44 SessionImpl.flushCollections - Processing unreferenced collections
[DEBUG] 09:08:44 SessionImpl.flushCollections - Scheduling collection removes/(re)creates/updates
[DEBUG] 09:08:44 SessionImpl.flushEverything - Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects
[DEBUG] 09:08:44 SessionImpl.flushEverything - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
[DEBUG] 09:08:44 Printer.toString - listing entities:
[DEBUG] 09:08:44 Printer.toString - com.mycompany.rts.tips.ContainerType{type=PIECES, description=Pieces of merchan
status=ACTIVE}
[DEBUG] 09:08:44 Printer.toString - com.mycompany.rts.tips.ContainerType{type=PALLETS, description=Pallets of merch
, status=ACTIVE}
[DEBUG] 09:08:44 SessionImpl.execute - executing flush
[DEBUG] 09:08:44 SessionImpl.postFlush - post flush
[DEBUG] 09:08:44 JDBCTransaction.commit - commit
Any thoughts? Thanks.
Ryan