This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Object Relational Mapping and the fly likes Controlling Hibernate Session with Spring Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Controlling Hibernate Session with Spring" Watch "Controlling Hibernate Session with Spring" New topic
Author

Controlling Hibernate Session with Spring

Roger Marin
Greenhorn

Joined: May 08, 2006
Posts: 16
Hello Ranchers,

We have a web app built with spring and hibernate that we are currently testing and profiling we found out that the hibernate session(managed by spring) isn't being closed after the request is over, thus causing very very serious performance issues, i was wondering if any of you could help me out figuring a way to somehow verify that the hibernate session is being handled correctly by spring or how could i implement some form of control over the hibernate session through spring?
pascal betz
Ranch Hand

Joined: Jun 19, 2001
Posts: 547
hello

do you use springs template mechanism for working with the session ? or do you just inject a sessionfactory you created with a SessionFactoryBean ?

if you work with the templates, idoubt that spring is not handling session properly.... if you do it yourself, then it's easy to forget to close/handle them in proper way.

can you show some code/config files ?

pascal
Roger Marin
Greenhorn

Joined: May 08, 2006
Posts: 16
Here's how we configure spring to handle hibernate:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!-- - Application context definition for "soma" DispatcherServlet. -->
<beans>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.query.substitutions">true 1, false 0, yes 'Y', no 'N'</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql:///soma</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password"></prop>
<prop key="hibernate.c3p0.min_size">2</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">300</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.idle_test_period">3000</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/com/soma/model</value>
</list>
</property>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>

And this is our Base Dao


package com.soma.dao;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;

import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.dao.DataAccessException;

public abstract class BaseDAO extends HibernateDaoSupport {


protected void save(final Object persistable) {
try{
getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
try{
Transaction tx = session.beginTransaction();
session.save(persistable);
tx.commit();
session.flush();
//releaseSession(session);
}

catch(HibernateException e)
{}


return persistable;
}});

}
catch(HibernateException e)
{
System.out.println("La excepci�n es: "+e.getMessage());
}
}


protected void delete(final Object persistable) {
try{
getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
try{
Transaction tx = session.beginTransaction();
session.delete(persistable);
tx.commit();
session.flush();
}

catch(HibernateException e)
{}


return persistable;
}});

}
catch(HibernateException e)
{
System.out.println("La excepci�n es: "+e.getMessage());
}
}


protected Object findById(final Class cl, final String tableName, final Long id) {
Object persistable = getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
List objects = new ArrayList();
SQLQuery query = session.createSQLQuery("select {obj.*} from "+tableName+" {obj} where obj.id="+id).addEntity("obj", cl);
objects = query.list();
Object resultObject = objects.get(0);
return resultObject;
}
}
);
return persistable;
}


protected List findAll(String sql) {
return getHibernateTemplate().find(sql);
}

}

What could be happening?
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

There is nothing in the code above that closes the session. Do you do this yourself elsewhere?


JavaRanch FAQ HowToAskQuestionsOnJavaRanch
Roger Marin
Greenhorn

Joined: May 08, 2006
Posts: 16
I thought spring manages all of this....where should i close the session?
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Ah my mistake...I read the code too quickly. You are using a Template, so yes Spring should be doing all the Session handling.
pascal betz
Ranch Hand

Joined: Jun 19, 2001
Posts: 547
@Paul: there is the openSessionInView interceptor that should open/close the session. at least i think so. this is of course tricky to test in a non-web environment.

@Roger:
- I would sugest you use a TransactionProxyFactoryBean instead of starting ending the TX manualy. less error prone.
- then i see some catch statements without logging! and you never rollback TX in case of exceptions.
- also i would check out the API of the HibernateTemplate it offers methods like delete()/save)=/saveOrUpdate() and so on...
- your findById method looks weird to me! why do you use SQL queries ? this is exactly what hibernate should do for you! why do you create an empty ArrayList() and then "throw it away" ?
if you got the class and the ID, then just do something like this:

or use one of the HibernateTemplate methods.... or use HQL but not SQL.
- better switch autocommit on your connection to false... just to be sure (though i think hibernate will complain if connection is in autocommit mode. not sure)



pascal
Roger Marin
Greenhorn

Joined: May 08, 2006
Posts: 16
Thank you both Paul and pascal.

Now,
I have to say this is a bit confusing to me since i am a newbie with ORM hibernate and spring, so please pardon my ignorance in case i say something stupid.

if spring is handling transactions for me how would i implement a TransactionProxyFactoryBean?
The code i posted isn't mine, but you are right, we shouldn't use sql but the thing is the whole app has sql querys everywhere everyone here is a newbie with both hibernate and spring and i guess there wasn't much time to learn the stuff...

Thank you!
pascal betz
Ranch Hand

Joined: Jun 19, 2001
Posts: 547
first check out http://www.springframework.org/docs/api/index.html?org/springframework/orm/hibernate/HibernateTemplate.html
and see what nice methods it offers :-)

a TransactionProxy is an Object wrapping a "target Object", implementing the same interface as the target. when you call method x() on the proxy, it will open a session/start a TX or reuse an existing TX (as required, you can configure this), forward the call to the target's method x(). it close the session/commit the TX before returning the return value (if method is not void). it will also handle commit/rollback of TX.

a FactoryBean (http://www.springframework.org/docs/api/index.html?org/springframework/transaction/interceptor/TransactionProxyFactoryBean.html) is spring concept: you specify the name of a Factory Bean (e.g. LocalSessionFactoryBean) in the spring config files, spring recognizes it as a factory and will not bind the FactoryBean in the spring application context but the bean that is created by the FactoryBean.

the TransactionProxyFactoryBean is a BeanFactory supplied with springframework. the API doc has an example how to set it up:
http://www.springframework.org/docs/api/org/springframework/transaction/interceptor/TransactionProxyFactoryBean.html
one thing you need is a Transaction Manager (bean "transactionManager" in the above example) which will probably this one: http://www.springframework.org/docs/api/index.html?org/springframework/transaction/interceptor/TransactionProxyFactoryBean.html


try if you get any further with this!
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Controlling Hibernate Session with Spring
 
Similar Threads
Spring and Hibernate
Where to use Spring?
is a good buy for me ? (coming from JSF and JPA)
iBatis follows JPA?
PrePersist doesn't work with Hibernate Template