Hi,
Can I use Hibernate cache in different transactions?
I need something like this:
class:
Code:
public class Expression {
private Log log = LogFactory.getLog(getClass());
private String id;
private String name;
private String expression;
CompiledExpression compiledExpression;
public Expression() {}
public Expression(String name, String expression) {
super();
this.name = name;
this.expression = expression;
}
public String getName() {
return name;
}
public String getExpression() {
return expression;
}
public CompiledExpression getCompiledExpression() {
if (compiledExpression == null) {
log.debug("compiling expression");
compiledExpression = JXPathContext.compile(getExpression());
}
return compiledExpression;
}
public void setExpression(String expression) {
this.expression = expression;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
I need to load new Expression and execute getCompiledExpression() only one time.
mapping:
Code:
<hibernate-mapping package="expressions">
<class name="Expression" table="EXPRESSIONS">
<id name="id">
<generator class="uuid"/>
</id>
<property name="name"/>
<property name="expression"/>
</class>
</hibernate-mapping>
configuration:
Code:
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:db/test</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="cache.use_query_cache">true</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping resource="expressions/Expression.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Now I can write:
Code:
public class ExpressionManager {
private Log log = LogFactory.getLog(getClass());
public ExpressionManager() {
SessionFactory sessionFactory =
new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Expression e = new Expression("MyExpr", "contains(name,'FFF')");
session.save(e);
e = (Expression)session.createQuery("from Expression").uniqueResult();
log.debug(e.getCompiledExpression());
e = (Expression)session.createQuery("from Expression").uniqueResult();
log.debug(e.getCompiledExpression());
session.getTransaction().commit();
sessionFactory.close();
}
public static void main(String[] args) {
new ExpressionManager();
}
}
I got:
[code]
...
INFO org.hibernate.cfg.SettingsFactory - Second-level cache: enabled
INFO org.hibernate.cfg.SettingsFactory - Query cache: enabled
INFO org.hibernate.cfg.SettingsFactory - Cache provider: org.hibernate.cache.EhCacheProvider
...
Hibernate: insert into EXPRESSIONS (name, expression, id) values (?, ?, ?)
Hibernate: select expression0_.id as id0_, expression0_.name as name0_, expression0_.expression as expression0_ from EXPRESSIONS expression0_
DEBUG expressions.Expression - compiling expression
DEBUG expressions.ExpressionManager - contains(name,'FFF')
Hibernate: select expression0_.id as id0_, expression0_.name as name0_, expression0_.expression as expression0_ from EXPRESSIONS expression0_
DEBUG expressions.ExpressionManager - contains(name,'FFF')
INFO org.hibernate.impl.SessionFactoryImpl - closing
INFO org.hibernate.connection.DriverManagerConnectionProvider - cleaning up connection pool: jdbc:hsqldb:db/test
...
[code]
I see select statement two times but I see compiling expression only one time. So, I think Expression object was loaded only one time, isn't it?
Next I write:
[code]
public class ExpressionManager {
private Log log = LogFactory.getLog(getClass());
public ExpressionManager() {
SessionFactory sessionFactory =
new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Expression e = new Expression("MyExpr", "contains(name,'FFF')");
session.save(e);
e = (Expression)session.createQuery("from Expression").uniqueResult();
log.debug(e.getCompiledExpression());
session.getTransaction().commit();
session = sessionFactory.getCurrentSession();
session.beginTransaction();
e = (Expression)session.createQuery("from Expression").uniqueResult();
log.debug(e.getCompiledExpression());
session.getTransaction().commit();
sessionFactory.close();
}
public static void main(String[] args) {
new ExpressionManager();
}
}
[/code]
and see:
[code]
...
Hibernate: select expression0_.id as id0_, expression0_.name as name0_, expression0_.expression as expression0_ from EXPRESSIONS expression0_
DEBUG expressions.Expression - compiling expression
DEBUG expressions.ExpressionManager - contains(name,'FFF')
Hibernate: select expression0_.id as id0_, expression0_.name as name0_, expression0_.expression as expression0_ from EXPRESSIONS expression0_
DEBUG expressions.Expression - compiling expression
DEBUG expressions.ExpressionManager - contains(name,'FFF')
INFO org.hibernate.impl.SessionFactoryImpl - closing
...
[code]
In this case Expression object was loaded two times. Can I change this behavior? Is it make sence to use cache in my case? In which cases need I use cache?