I want to implement a tree-like view to the front-tier with an one-to-many mapping. the object in my app is a Category class which has a children with List type to contain sub category and a parent field to reference the Parent category. so the relationship between Category is one-to-many. however,i want to cache the result data to memory so i turn on the cache with provider class "net.sf.hibernate.connection.DatasourceConnectionProvider" and "hibernate.cache.use_query_cache" property to "true" follow with the hibernate documentation. i also use query.setCacheable(true) in my code.
But from the printed hibernate sql in console ,the cache see to be never used (every invoke to the queryObject() , the sql would print again!!)
I want to know if the cache data only available in the same session? so whe close the session,the cache would flush and clean?
I use hibernate2.1.4/mysql4.0.18/tomcat5/windows2000/jdk.1.4.2
CmsCategory2.java
Code:
package com.bess.cms.cms;
import java.util.List;
import java.util.ArrayList;
public class CmsArCategory2 {
private int id;
private String templateid;
private String type;
private String name;
private String level;
private String parentid;
private String remark;
private String status;
private String navpath;
private String url;
private List children = new ArrayList();
private CmsArCategory2 parent;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getParentid() {
return parentid;
}
public void setParentid(String parentid) {
this.parentid = parentid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getTemplateid() {
return templateid;
}
public void setTemplateid(String templateid) {
this.templateid = templateid;
}
public String getNavpath() {
return navpath;
}
public void setNavpath(String navpath) {
this.navpath = navpath;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
public CmsArCategory2 getParent() {
return parent;
}
public void setParent(CmsArCategory2 parent) {
this.parent = parent;
}
public void addChild(CmsArCategory2 child)
{
getChildren().add(child);
child.setParent(this);
}
public void removeChild(CmsArCategory2 child)
{
getChildren().remove(child);
child.setParent(null);
}
public boolean isRoot(){
return getParent() == null;
}
}
hibernate.cfg.xml:
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">java:comp/env/jdbc/MysqlDB</property>
<property name="show_sql">true</property>
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<property name="connection.provider_class">net.sf.hibernate.connection.DatasourceConnectionProvider</property>
<property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.Provider</property>
<property name="hibernate.cache.use_query_cache">true</property>
<!-- Mapping files -->
<class name="com.bess.cms.cms.CmsArCategory2" table="cms_ar_category">
<cache usage="read-write"/>
<id name="id" type="int" column="id" unsaved-value="0">
<generator class="identity"/>
</id>
<property name="status" column="status" type="string"/>
<property name="templateid" column="templateid" type="string"/>
<property name="name" column="name" type="string"/>
<property name="type" column="type" type="string"/>
<!--property name="parentid" column="parentid" type="string"/-->
<property name="remark" column="remark" type="string"/>
<property name="level" column="level" type="string"/>
<property name="navpath" column="navpath" type="string"/>
<property name="url" column="url" type="string"/>
<many-to-one name="parent" column="parentid" class="com.bess.cms.cms.CmsArCategory2"/>
<bag name="children" table="cms_ar_category" inverse="true" lazy="false">
<key column="parentid"/>
<one-to-many class="com.bess.cms.cms.CmsArCategory2" />
</bag>
</class>
</session-factory>
</hibernate-configuration>
database scheme:
Code:
CREATE TABLE `cms_ar_category` (
`id` int(11) NOT NULL auto_increment,
`templateid` varchar(10) default NULL,
`type` varchar(10) default NULL,
`name` varchar(100) default NULL,
`level` char(2) default NULL,
`parentid` varchar(10) default NULL,
`navpath` varchar(200) default NULL,
`remark` varchar(100) default NULL,
`status` char(1) default 'y',
`url` varchar(200) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM;
HibernateUtil.java with some code like queryObject()
Code:
public static List queryObject(String hql) {
Session ss = null;
List ret = null;
try {
ss = HibernateUtil.currentSession();
Query q = ss.createQuery(hql);
q.setCacheable(true);
ret = q.list();
} catch (HibernateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
HibernateUtil.closeSession();
} catch (HibernateException e) {
e.printStackTrace();
}
}
return ret;
}
test code :
every time i invoke the getCategoryChildren() function and the sql printed to the console again!!! :-(
Code:
public List getCategoryChildren(int parentid){
return HibernateUtil.queryObject("FROM CmsArCategory2 as c WHERE c.parent.id=" + parentid);
}
ehcache.xml :
Code:
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false"
/>
</ehcache>