-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Caching strategy
PostPosted: Mon Nov 10, 2003 3:32 pm 
Beginner
Beginner

Joined: Wed Aug 27, 2003 8:55 am
Posts: 28
Location: Dallas, TX
I have a few tables that contain some simple name-value pairs that are used in some drop-down boxes in a web application. I like having this data in the database, because this data changes periodically. However, it is stable enough that it should be cached. Ideally, I would like to create a cache for all of these that expires regularly (once/hour).

I would like any class that needs one of these lists of NV pairs to ask the pesistance layer for this list. This would, in turn, get the objects from cache (that are automatically refreshed once per hour).

My question is how do to this transparently with Hibernate. JCS caching does not seem to do the trick, because it is no help in find() calls like:

Code:
"from FreightClass freightClass where freightClass.status = ? ", "ACTIVE", Hibernate.STRING);


or

Code:
find(" from ContainerType containerType");


This seems simple (just slurp the whole table once per hour) but I can't see away to do it. Can anybody point me in the write direction? This obviously isn't an unusual feature.

Thanks.

Ryan


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 10, 2003 6:02 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
Hibernate 2.1 has query based caching so your find results will be cached.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 11, 2003 11:26 am 
Beginner
Beginner

Joined: Wed Aug 27, 2003 8:55 am
Posts: 28
Location: Dallas, TX
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


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 11, 2003 11:37 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
did you enable the query cache??

hibernate.cache.use_query_cache


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 11, 2003 11:59 am 
Beginner
Beginner

Joined: Wed Aug 27, 2003 8:55 am
Posts: 28
Location: Dallas, TX
gavin wrote:
did you enable the query cache??

hibernate.cache.use_query_cache


Ah, music to my ears:

Code:
[DEBUG] 09:56:27 QueryCache.get - checking cached query results in region: net.sf.hibernate.cache.QueryCache
[DEBUG] 09:56:27 QueryCache.get - returning cached query results
[DEBUG] 09:56:27 SessionImpl.doLoadByClass - loading [com.michaels.rts.tips.FreightClass#50]
[DEBUG] 09:56:27 SessionImpl.doLoad - attempting to resolve [com.michaels.rts.tips.FreightClass#50]
[DEBUG] 09:56:27 ReadOnlyCache.get - Cache hit: 50


That was it. Thanks.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.