Results 1 to 9 of 9

Thread: Hibernate 3.1 and OpenSessionInView/Long Conversation

  1. #1
    Join Date
    Dec 2005
    Posts
    5

    Default Hibernate 3.1 and OpenSessionInView/Long Conversation

    In Hibernate 3.1 the default connection release mode changed from ON_CLOSE to auto. That means that the connection is closed after the end of the transaction (Connection Release Modes).
    I am using Hibernate and the Spring transaction facility with a hand written interceptor, that does the following things:
    Code:
    preHandle:
      check if a Hibernate Session is in the HttpSession.
        if so reconnect and bind to the TransactionSyncronizationManager
        if not, create a new Session, bind to the TransactionSyncronizationManager
        and put it into the HttpSession
    
    postHandle:
      unbind the session from TransactionSyncronizationManager
      if a special flag is set, close the session
      else disconnect the session, but let it in the HttpSession
    I think this should be the right pattern for long conversations and Spring
    (Long Conversations)

    The problem is now the following: The servlet calls a business method, which is transactionally marked via the Spring transaction facility. It completes the method and commits, and therefore Hibernate 3.1 closes the connection. What now happens, is clear:
    If a a lazy initialized object is accessed in the view rendering phase a LazyInitializationException is thrown.
    So what can we do? Its possible to change the default connection release mode to ON_CLOSE, but this link and this link discourages it.
    Another possibility is to start a transaction in my interceptor, when I open/reconnect the Session. But then database locks are kept during the view rendering phase, so this is also not a good idea.
    The Hibernate page advises also to use two transactions (http://www.hibernate.org/43.html#A9). How can I accomplish this?
    Any other suggestions?


    I am not using the OpenSessionInView pattern, but I think it has the same problem. Is anybody using the OSIV pattern with Sping and Hibernate 3.1? If it is working with OSIV, whats the problem with my long conversation interceptor?

    Thank you!

  2. #2
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Long transactions are discussed quite a lot since they could be a solution to a lot of problems but the implementation is not that easy and in my experience, depends on what are your requirements.
    I think you should not make too many assumpations on the flushing or releasing mode unless you really have to.
    Note that is not desirable to have long transactions since the connection can drop and the tx will block/lock your database. This leaves with having small transactions which at some point have to be committed as part of a big tx.
    Spring WebFlow does this on the webtier and I highly recommend it. For the business logic the most common solution is detaching/attaching objects and store them between various requests/logic steps in a well known location.
    The objects should be committed only in the last step so that the database is not left in an inconsistent state.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  3. #3
    Join Date
    Dec 2005
    Posts
    5

    Default

    Quote Originally Posted by costin
    Long transactions are discussed quite a lot since they could be a solution to a lot of problems but the implementation is not that easy and in my experience, depends on what are your requirements.
    I do not use long transactions, but only long conversations.
    Quote Originally Posted by costin
    I think you should not make too many assumpations on the flushing or releasing mode unless you really have to.
    Ok, but what should I do? The OSIV pattern does not work with Hibernate 3.1 when other transacations are started in the business code.

  4. #4
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    I do not use long transactions, but only long conversations.
    One solution that usually works is to open/close sessions per web request and reattach the objects.

    Ok, but what should I do? The OSIV pattern does not work with Hibernate 3.1 when other transacations are started in the business code.
    OSIV is a pattern implmentation for a particular problem - you can either extend it or write one of your own. Since you want/have to do the long conversation demarcation yourself, you have to extend the filter anyway.
    And OSIV does work with transactions started in the business layer - from the javadoc:
    This filter works similar to the AOP HibernateInterceptor: It just makes Hibernate Sessions available via the thread. It is suitable for non-transactional execution but also for business layer transactions via HibernateTransactionManager or JtaTransactionManager. In the latter case, Sessions pre-bound by this filter will automatically be used for the transactions and flushed accordingly.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  5. #5
    Join Date
    Dec 2005
    Posts
    5

    Default

    Quote Originally Posted by costin
    And OSIV does work with transactions started in the business layer - from the javadoc:
    Not with Hibernate 3.1, because Hibernate 3.1 closes the connection after a commit. So if you use transactions in the business layer, the following things happen:
    - A transaction is started, and bound to the Hibernate Session.
    - The transaction commits or rolls back
    - Hibernate closes the connection
    - The view is rendered, with a Hibernate Session with a closed connection.
    - BANG: LazyInitialisationException

    I hope my problem is clearer now.
    One solution could be to start the transaction earlier, in the interceptor. But this creates problems with open locks in view. Or maybe we could start a transaction in read-only mode....

  6. #6
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Not with Hibernate 3.1, because Hibernate 3.1 closes the connection after a commit.
    Spring's LocalSessionFactoryBean will set on_close if you are using Hibernate 3.1 and you haven't specified a different closing mode.
    The reference documentation from HB 3.1.3 state that on_close release mode is used by default and not after_transaction as you suggest.
    What HB and Spring version are you using?
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  7. #7

    Default support for after_transaction

    According to Hibernates docs, release mode on_close is 'highly discouraged', after_transaction is the default with jdbc transactions.
    http://www.hibernate.org/hib_docs/v3...ection-release

    Will there be any support for hibernate release mode after_transaction in the (near) future?

    thanks
    Last edited by michaelfortin; May 10th, 2006 at 04:07 PM.

  8. #8
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Take a look at the javadoc for HibernateTransactionManager - especially setPrepareConnection.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  9. #9

    Default

    Hi Costin,

    I have looked at HibernateTransactionManger as you suggest and LocalSessionFactoryBean's exposeTransactionAwareSessionFactory and useTransactionAwareDataSource and I've gone so far as to look at the source in an attempt to set after_transaction. Every configuration I've tried ultimatelty gives me an InvalidIsolationLevelException.One thing I'm puzzled about in hiternateTransactionManager, it checks the isolation level against the default (line 471) and the default is set to -1. As far as I know there is no such isolation level, is this a bug or is it on purpose to prevent usage of after_transaction? Setting prepareConnection to false will always cause this exception, or am I missing something?
    Last edited by michaelfortin; May 12th, 2006 at 02:46 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •