Announcement Announcement Module
Collapse
No announcement yet.
Tx management bringing LazyInitializationException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Tx management bringing LazyInitializationException

    Hello

    I 'm working in this project where i 'm stucked with a problem i just can't understand

    Scenario is an application using spring 2.5 (although configuration is as spring 1.x) and hibernate 3.2, configuring transactions in a declarative form using names of methods (with wildcards).

    Briefly, when i changed transactionAttributes to rollback on certain checked exception a LazyInitializationxception occurs at a certain point in the code. What's weird for me is that when i change back and leave transactionAttributes (for the method is causing this) only with PROPAGATION_REQUIRED then that LazyInitializationException doesn't show up and everything works out.

    Going deeper in detail, transactionAttribute configuration that works ('aka' configuration1) is this:

    <prop key="find*">PROPAGATION_REQUIRED</prop>

    Then all methods whose names start with 'find' in services/daos should open a new transaction or use some existent (if any).

    After trying out this configuration (which worked out fine), i figured out that i had some checked exceptions being thrown from those methods and i wanted to rollback when those exceptions showed up. (Default spring behaviour is to rollback only on unchecked exceptions being thrown)

    So i tried out with configuration2:

    <prop key="find*">PROPAGATION_REQUIRED,-BusinessException</prop>

    BusinessException is a checked exception and this config is supposed to rollback transaction on those methods which are transactional and throw BusinessException.

    This application i 'm working on is a Desktop application (NOT-WEB), anyway we tried to implement Open Session In View pattern using the spring-provided HibernateInterceptor.


    A kind of sequence diagram would be,

    1) Application user takes some action that fires HibernateInterceptor (Hibernate Session is opened)
    2) Some query is executed so that certain object is retrieved from the database, this object contains a collection which will be lazy fetched sometime. (At this point we 're supposed to be in the scope of some session but not within any transaction)
    3) Some transactional method (find*) was called and we enter on it (Now we 're within a Session and in a Transaction)
    4 ) Somehow, inside the trasactional method we get to reach a reference to the same (identity) object retrieved in step 2 and the isEmpty method is called on it's collection so that now it's necessary to lazy fetch that collection..
    5) On this step we would get out of the transactional method we entered on step 3 and program would continue until delivering some output to the application user.

    Whenever i use transactionAttributes' configuration1 program runs with no errors.
    Whenever i use transactionAttributes' configuration2 program throws a LazyInitializationException on step 4: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ar.com.condortech.model.appserver.users.Admin.admi nistrationGroups, no session or session was closed

    I worked out to do some tests inspects thinking that the HibernateInterceptor's OpenSessionInView thing could be messing around with different Sessions or closed Sessions that could be generating the LazyInitializationException.

    * I inspected the hibernate Session opened in step 2 by HiberanteInterceptor and is the same (identity/hashCode) object as in step 4.

    * I inspected that [Session].getTransaction().isActive() was false before step 3 and true in step 4.

    * Finally i tested that [Session].isClosed() was false even in step 4.


    Can anyone bring out some idea about why is this Lazy showing up?

    thank you so much,

    and sorry for verbosity of this email

    cheers

  • #2
    You could just tell me that kind of configuration (adding checked exceptions rollback) worked fine for you at least...



    thanks

    Comment


    • #3
      Hi

      On Configuration2 you rollback on BusinessExceptions, in Configuration1 not.

      So Lazy Exception appears when you rolloback.

      Why? -> Sessions are clear on rollbacks and all entities are evicted.

      After evict an object LazyInitialization fail. The object is detached.

      Hope that help.

      regards
      Last edited by chelu; Aug 29th, 2008, 03:53 AM.

      Comment


      • #4
        Thanks!

        I didn't know that:

        > Why? -> Sessions are clear on rollbacks and all entities are evicted.


        And that certainly explains it all!...

        anyway.., is there some configuration to avoid clearing the session while rollbacking?, in fact i can't imagine why would that be necessary.


        thanks!

        Comment


        • #5
          On rollbacks, Objects in sessions contains invalid state and must be discarded.

          see doRollback in HibernateTransactionManager :

          Code:
          	protected void doRollback(DefaultTransactionStatus status) {
          		HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
          		if (status.isDebug()) {
          			logger.debug("Rolling back Hibernate transaction on Session [" +
          					SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]");
          		}
          		try {
          			txObject.getSessionHolder().getTransaction().rollback();
          		}
          		catch (org.hibernate.TransactionException ex) {
          			throw new TransactionSystemException("Could not roll back Hibernate transaction", ex);
          		}
          		catch (HibernateException ex) {
          			// Shouldn't really happen, as a rollback doesn't cause a flush.
          			throw convertHibernateAccessException(ex);
          		}
          		finally {
          			if (!txObject.isNewSessionHolder()) {
          				// Clear all pending inserts/updates/deletes in the Session.
          				// Necessary for pre-bound Sessions, to avoid inconsistent state.
          				txObject.getSessionHolder().getSession().clear();
          			}
          		}
          	}
          Is not good idea change this behavior.

          Comment


          • #6
            Yes, i see...

            Some object will have invalid state...

            but some other won't.., as i 'm using an open session in view approach.., perhaps it happens that after rollbacking.., i 'd use some objects brought from the db to render the error message to the user...

            but if i ask they objects for lazy properties those calls will fail...

            but..,

            as you say, some objects in the session may contain invalid state..., and although some others not.., i still can't imagine any way of discriminating objects that were created in the session in the transaction that failed.., and those which were in the session before the transaction was even started.

            So.., i guess that the tradeoff is to clear the whole session.

            cheers..,
            and lot of thanks.

            Comment


            • #7
              I supouse that you can refresh the objects that you need after the rollback

              regards,

              Comment

              Working...
              X