2

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.

Doppelganger
  • 20,114
  • 8
  • 31
  • 29

1 Answers1

4

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 Roy
  • 8,452
  • 10
  • 60
  • 84
  • 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 Aug 26 '10 at 15:34
  • @Doppelganger I have updated my answer to reflect on the use of OpenEntityManagerInViewFilter – Thierry Roy Aug 26 '10 at 16:47
  • 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 openEntityManagerInViewFilter java.lang.NoClassDefFoundError: org/springframework/dao/DataAccessResourceFailureException I'll check back to you if I can make it work. Also, what do you mean by injecting an emf into the filter? – Doppelganger Aug 27 '10 at 14:00
  • @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 Roy Aug 27 '10 at 14:27
  • @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 Aug 27 '10 at 18:28
  • 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 Aug 27 '10 at 19:31