Monday, December 22, 2008

Hibernate/JPA objects in an HTTP session

Last week I ran into an unexpected problem.  

My application has a User object, which contains various fields.  User also has a JPA-managed One-To-Many relationship with something called Store.  This relationship had been working fine (and in fact through this story never stopped working).

For the first time, last week, I added a JPA-managed relationship between User and an entity class called QuickListEntry.  QuickListEntry in turn has a relationship with Product, which in turn has plenty of other relationships with other entities.

We're using Struts 2, which is only marginally relevant here.

In Action A, we load up the User object from the SecurityContext, do some stuff with him, and then stuff him into the Session for access later.  In Action B, we pull him out of the session and read his data, including his QuickListEntries.  Well what do you know -- I'm getting a Hibernate LazyInitializationException.  This has never happened before.  It never happed with the User's Stores.  What's going on?

Well here's what's going on.  When the User is stuffed into the Session, he is disconnected from the JPA EntityManager.  When he is pulled out of the Session, his extended relationships (User to QuickListEntry to Product) can't be followed, because he is disconnected from the EntityManager.  

So the most correct solution in this case is not to stuff the User object into the Session at all.  Either stuff the userid in there (which is probably harmless) and then use the userid to re-load the User from the DB in every Action's prepare() method; or pull the User from the SecurityContext on every page load (again, I'd put this in the prepare() method of every Action class).

Wednesday, December 17, 2008

Eclipse/Tomcat note to self

Tomcat stops reading config data.  Error with docBase, directory does not exist or is not readable.  Here's what seemed to help:

Remove Tomcat as a server.  Close and restart Eclipse.  Add Tomcat as a server, with the correct project.  Re-add /Catalina/localhost/my.xml.  Make sure the entry is in my.xml and not in server.xml.