PDA

View Full Version : using HibernateInterceptor with TransactionProxyFactoryBean



bdjones
Sep 13th, 2004, 01:17 PM
Is there a way to use HibernateInterceptor with the TransactionProxyFactoryBean? I'm trying to apply a HibernateInterceptor to a TransactionProxyFactoryBean in the applicationsContext.xml. Does someone have an example of how to "wire-up" the interceptor to the TransactionProxyFactoryBean's postInterceptors attribute in xml? Or is the interceptor only used with a ProxyFactoryBean? Obviously, I'm new so any help would be appreciated.

irbouho
Sep 13th, 2004, 02:03 PM
Since you are using TransactionProxyFactoryBean, you do not need to use HibernateInterceptor. Just configure a HibernateTransactionManager and provide it as the transactionManger of your TransactionProxyFactoryBean.

HibernateTransactionManager binds a new Hibernate Session to the thread before a method call, closing and removing it afterwards in case of any method outcome. If there already was a pre-bound Hibernate Session, HibernateTransactionManager will reuse it.

For an example of using HibernateTransactionManager, search the forums.
For an example of using HibernateInterceptor, take a look at Spring AOP with Hibernate (http://www.springframework.org/docs/wiki/Spring_AOP_with_Hibernate.html).

HTH

bdjones
Sep 13th, 2004, 04:34 PM
Well, let me back up. I want to be able to access lazily initialized collections.

Here is what I have :

A hibernate DAO class:


public class StudentDAOhbm extends HibernateDaoSupport implements StudentDAO{

/** Creates a new instance of StudentDAOhbm */
public StudentDAOhbm() {
}

public Student loadStudent(int id) {
return (Student) getHibernateTemplate().load(Student.class, new Integer(id));
}

}


The pertinent xml configuration is as follows (from both spring-servlet.xml and applicationContext.xml):

<bean id="studentManagerTarget" class="somecompany.DAO.hbm.StudentDAOhbm">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>

<bean id="studentManDao" class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">
<property name="transactionManager"><ref local="transactionManager"/></property>
<property name="target"><ref local="studentManagerTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="store*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean id="studentDetailController" class="somecompany.web.StudentDetailController">
<property name="studentMan">
<ref bean="studentManDao"/>
</property>
</bean>




A controller class as follows:


public class StudentDetailController implements Controller &#123;

private StudentDAO studentMan;

public ModelAndView handleRequest&#40;HttpServletRequest request, HttpServletResponse response&#41;
throws ServletException, IOException &#123;

int studentId = RequestUtils.getIntParameter&#40;request, "studentId", 0&#41;
Student student = studentMan.loadStudent&#40;studentId&#41;;
Set names = student.getNames&#40;&#41;;

Map myModel = new HashMap&#40;&#41;;
myModel.put&#40;"student",student&#41;;


return new ModelAndView&#40;"studentDetailView", "model", myModel&#41;;
&#125;



Now finally the Student class

public class Student extends Person implements Serializable &#123;

// many other attributes

private Set names;

// other constructors

/** default constructor */
public Student&#40;&#41; &#123;
&#125;


public Set getNames&#40;&#41; &#123;
return this.names;
&#125;

public void setNames&#40;Set names&#41; &#123;
this.names = names;
&#125;

&#125;


Now when I run this I get an error as follows:

net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed

caused by the following line in the controller class :

Set names = student.getNames();


I realize that the method getNames is accessing a collection that is lazily initialized. How do I access a lazily initialized set such as the set in the example above? Is there a good example somewhere? I guess I would like some direction. Does anyone have a good idea that I can follow? Again, any help at all is greatly appreciated.

irbouho
Sep 13th, 2004, 04:49 PM
You can configure a OpenSessionInViewFilter in your web.xml to keep your Hibernate Session open for View Layer.

bdjones
Sep 13th, 2004, 05:48 PM
I tried the OpenSessionViewFilter in my web.xml file, and that didn't work. I get the same error as in the previous post.

I'm guessing my OpenSessionInViewFilter is not configured properly.

What am I missing?

Here is my web.xml file:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http&#58;//java.sun.com/xml/ns/j2ee"
xmlns&#58;xsi="http&#58;//www.w3.org/2001/XMLSchema-instance"
xsi&#58;schemaLocation="http&#58;//java.sun.com/xml/ns/j2ee http&#58;//java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-hibernate.xml</param-value>
</context-param>
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate.support.OpenSess ionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListe ner</listener-class>
</listener>

<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServl et</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet>
<servlet-name>findstudent</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>findstudent</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>

</web-app>

irbouho
Sep 13th, 2004, 05:54 PM
Do you call jsp from your web agent?


<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>

I think that the OpenSessionInViewFilter should be mapped to


<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.htm</url-pattern>
</filter-mapping>

as the Hibernate Session should be opened before your controller is invoked and closed after the View has finished rendering the output.

HTH

bdjones
Sep 13th, 2004, 06:25 PM
Yes, you were right. I changed the .jsp to .htm and it seems to work now.

Thank you so freaking much.