Hi,
I'm still pretty new to Hibernate, so maybe I understood something wrong.
My application is using EHCache as the second level cache provider.
I test if the cache is working properly by measuring the execution time of a SQL statement which is located in a for-loop, beeing executed 10 times.
Code:
ContentDAO dao = new ContentDAO();
Session session = dao.getSession();
TestTimer timer = new TestTimer();
for(int i=0; i<10; i++)
{
timer.resetStart();
dao.findContentByUserid(1);
timer.printDuration("CACHE CHECK");
}
After the application started up the cache works fine until a session.flush() is executed.
Thenceforth when executing a SQL statement, hibernate looks up the cache, says that it has not found anything, executes the SQL statement on the database and stores the result in the cache. (According to the sessionfactory statistics).
From that point on, the problem is globally, so every currently or newly opened session never hits the cache, but looks it up and stores the results into it.
I'm using the session-per-conversation pattern.
No errors, exceptions or warnings occur during execution.
using
Hibernate 3.2
Postgresql 8.4
Tomcat 6
EHCache 1.2.3
JSF 1.2
Here is the hibernate.cfg.xml (I cut off the mappings)
Code:
<property name="dialect">
org.hibernatespatial.postgis.PostgisDialect
</property>
<!-- get connection pool from tomcat jndi, configured in the tomcat/conf/server.xml file -->
<property name="connection.datasource">java:comp/env/jdbc/postgres</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="max_fetch_depth">1</property>
<!-- prints out the generated SQL commands -->
<property name="hibernate.show_sql">true</property>
<!-- Generate hibernate statistics: get them via SessionFactory.getStatistics() -->
<property name="hibernate.generate_statistics">true</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">org.hibernate.context.ManagedSessionContext</property>
<!-- Second-level caching -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.provider_configuration_file_resource_path">/ehcache.xml></property>
the ehcache.xml file
Code:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="true" monitoring="autodetect">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="7200"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="3600"
/>
</ehcache>
Here is the PhaseListener which implements the long conversation pattern
Code:
private TestTimer timer = new TestTimer();
@Override
public void afterPhase(PhaseEvent arg0)
{
if(arg0.getPhaseId() == PhaseId.RESTORE_VIEW)
{
try
{
HibernateSessionBinderBean.getInstance().getSemaphore().acquire(); //waits until the older request is processed
}
catch (InterruptedException e)
{
e.printStackTrace();
}
Session session = HibernateSessionBinderBean.getInstance().getSession();
if(session == null || !session.isOpen() || !session.isConnected())
{
//create new session
session = HibernateSessionManager.getOpenNewSession();
session.setFlushMode(FlushMode.MANUAL);
HibernateSessionBinderBean.getInstance().setSession(session);
}
Session previouslyBoundSession = ManagedSessionContext.bind((org.hibernate.classic.Session)session);
if(previouslyBoundSession != null)
{
previouslyBoundSession.close();
}
session.beginTransaction();
checkCache();
timer.resetStart();
}
if(arg0.getPhaseId() == PhaseId.RENDER_RESPONSE)
{
timer.printDuration("REQUEST PROCESSING DONE");
printStatistics();
Session session = ManagedSessionContext.unbind(HibernateSessionManager.getSessionFactory());
session.getTransaction().commit();
session.flush();
HibernateSessionBinderBean.getInstance().getSemaphore().release(); //http request processing done, release signal
}
}
Until now I spent a lot of hours on that problem and I would be really happy if someone can help me to solve that.
Best regards
Humppa