- This topic has 4 replies, 2 voices, and was last updated 17 years, 11 months ago by Peter L. Berghold.
-
AuthorPosts
-
Peter L. BergholdMemberHi folks,
I have a simple “change password” form, form bean and action that allows a user to change their password as it is entered in the database I keep all
that wonderful information in.Further I have a “service” that handles all interations with the account object and when I invoke the update method of that service which is:
/** * Takes an already persisted Account object and updates the row * in the database that reflects that object. * * @param acct (Account) the account being updated in the database */ public void updateAccount(Account acct){ Session session = null; Transaction tx = null; try { session = HibernateSessionFactory.getSession(); tx = session.beginTransaction(); session.update(acct); tx.commit(); session.flush(); } catch (HibernateException e) { session.flush(); throw new RuntimeException(e); } }
Which more or less follows the design pattern in the BasicDB source that is given as part of the Hibernate tutorial given on this site.
However, when I exectue this method I get the following rather bizarre error:
java.lang.RuntimeException: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
at org.bcdc.hbm.services.AccountService.updateAccount(AccountService.java:229)
at org.bcdc.struts.action.ChangePasswordAction.execute(ChangePasswordAction.java:80)etc…
Anybody shed any light on this? Thanks in advance,
Haris PecoMemberPeter,
You have probably got this exception, because you forgot to close the previous session.Use this pattern for your actions :
public void updateAccount(Account acct) { Session session = null; Transaction tx = null; try { session = HibernateSessionFactory.getSession(); tx = session.beginTransaction(); session.update(acct); tx.commit(); // session.flush(); // commit call flush } catch (HibernateException e) { if (tx != null) tx.rollback(); throw new RuntimeException(e); } finally { if (session != null) session.close(); } }
Regards
Peter L. BergholdMemberPeco,
Thanks for your response.
I went ahead and retrofitted the rest of the methds in my AccountService singleton to include the design pattern
| | finally { if ( session != null) session.close(); } |
which I’ve noticed called out for in other tutorials and doco on the subject of Hibernate here and at other sites. When I’ve done this in the past I’ve created a new problem as is evidenced by this error:
10:14:40,147 ERROR LazyInitializationException:19 – failed to lazily initialize a collection of role: org.bcdc.hbm.tables.Account.accountRoles, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.bcdc.hbm.tables.Account.accountRoles, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:138)
at org.bcdc.misc.sys.RolesBasedMenuWidget.getPersonalMenu(RolesBasedMenuWidget.java:50)
at org.apache.jsp.menus.public_.general_jsp._jspService(general_jsp.java:111)which makes sense to me the more I work with Hibernate and get used to the way it does things. From a high level perspective what is going on in my code is a user logs in, if the login reflects an existing account and the password entered is correct the Account pojo gets stored as an attribute to the HTTP session for later use. (Maybe I’d better not do that… read on) That account object is used all over the place in the application for one thing to determine what roles that account plays on the web site. For instance, certain folks get to use certain menus and see certain views of data. etc.
So, when I’m closing the session (at least this is how I translate the error above) and I try to retrieve one of attribuites in the Account object (for instance the relationship Person -> Person.given_name) since a session is not open at this point Hibernate can’t perform the retrieval.
Am I on the right track or am I totally clueless?
Given all that the question remains: when is the right time to close a session? One solution I was toying with seems rathe hokey to me but might solve the problem: is to at the “bottom” of my JSP pages that have done a bunch of DB operatons through Hibernate is to hae some code that looks like:
<% org.hibernate.Session hibernateSessoin = org.bcdc.hbm.HibernateSessionFactory.getSession(); if ( hibernateSesion != null ) hibernateSession.close(); %>
This solution doesn’t “feel right” to me. Comments? Thoughts?
Haris PecoMember
Peter L. BergholdMemberPeco,
Thanks again… ok… sometimes ya gotta use a 2×4 (clue-by-four?) to get my attention. I think you pointed this page out to me before and I couldn’t grok what in the world was going on with that filter. Now a bunch of months later it makes sense to me.
Thanks!
-
AuthorPosts