views:

47

answers:

1

First I need to acknowledge the fact that I'm new to EJB, JPA and Spring, so many of the things I believe as true could be wrong.

I'm building an EJB application where there's an stateless session bean used to retrieve many JPA (Hibernate) entities. The problem, which I believe is a widespread problem, is that I cannot traverse the relationships of those entities when the stateless returns any instance. I get the dreaded LazyInitializationException. In many cases I found that using eager fetching I could avoid the exception, but this felt more like a workaround than a real fix. After lots of googling, I found that (since I'm using spring) probably the most intrusive way to accomplish this was using OpenSessionInViewInterceptor.

Reading this looks like it's easy to use, but I can't map the files mentioned in the article. One possible explanation is that I'm using Spring 3, so the names for the files might have changed. I do have a spring3app-servlet.xml where beans are being declared. I also have a web.xml where filters are set (this file I believe that was used with spring 2.0, but it still works with 3.0).

Further searching made me realize that the filenames weren't my only concern, since I don't have any SessionFactory bean, which I believe it's necessary for this to work. This lead me to search info about the SessionFactory bean.

That search made me realize that I probably need .hbm.xml files. I'm not sure if those files are really needed, or if they where a requisite for legacy hibernate-spring versions.

tl;dr: I want an OpenSessionInViewInterceptor. Do I need a SessionFactory Bean? Do I need .hbm.xml files? Where can I find all the information to set this up?

Edit:

Maybe the solution is using OpenSessionInViewFilter. I'm trying to use it but it still fails with the same exception. I'm reading this in search of a fix.

+1  A: 

First, if you're going for an all out JPA solution, you should use OpenEntityManagerInViewFilter. Which does something similar to OpenSessionInViewInterceptor, but for JPA

As for the session bean, you will always get a LazyInitializationException since the object is loaded in a different session. Lazy fields are only accessible in the current http request. If you access the field in another http request you will get a LazyInitializationException.

(by the way hibernate define a http request as "Session". But a Spring session covers multiple http request. Yes this is confusing).

What you can do to avoid the LazyInitializationException is:

  1. Reload the session bean. For example:

    MyObject objectFromDb = objectDAO.find(objectFromSession.getId());

  2. Or initialize the field when you set the field in a session bean:

    Hibernate.initialize(field);

(don't forget to recurse over all children fields)


Ok, since this is the same session, you do need a OpenEntityManagerInViewFilter/OpenSessionInViewInterceptor, which will create an Hibernate session for each Http request. So put an entry in your web.xml:

    <filter>
        <filter-name>JpaFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>JpaFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>

The OpenEntityManagerInViewFilter is similar. Also make sure that your "entityManagerFactory" bean is injected in your filter.

Thierry-Dimitri Roy
I'm not covering multiple requests, it's all within the same request. That's why I believe that a spring-managed-session should fix my problem.
Doppelganger
@Doppelganger I have updated my answer to reflect on the use of OpenEntityManagerInViewFilter
Thierry-Dimitri Roy
I'm trying to make the filter work, and I have many problems. I added the maven dependency of spring-orm and now I'm having this problem:10:55:06,457 ERROR [[/system]] Exception starting filter openEntityManagerInViewFilterjava.lang.NoClassDefFoundError: org/springframework/dao/DataAccessResourceFailureExceptionI'll check back to you if I can make it work.Also, what do you mean by injecting an emf into the filter?
Doppelganger
@Doppelganger OpenEntityManagerInViewFilter needs a emf to work properly. I don't know how your injection are done (aytowired by name? explicit?) Just make sure that the Filter has an emf injected (it needs one to function properly!)
Thierry-Dimitri Roy
@Thierry-Dimitri Roy I'm injecting it with the @EJB annotation, on a ssb which I use as a DAO, I don't know how to use/what to do with the filter, besides adding the XML you gave me in web.xml
Doppelganger
Now I'm trying to find the solution in this old post from someone with the same problem http://forum.springsource.org/showthread.php?t=76488
Doppelganger