3 Replies Latest reply on May 22, 2007 3:29 PM by imario

    release connection after lazy init in view

    imario

      Hi!


      I would like to know if seam handle (if at all) the following problem:
      (BTW: I looked at the source, but couldn't find something in this direction)

      You load an entity from the database which has a lazy OneToMany within.
      Now, when you do not access this list from your action class or any other managed code the session will be disconnected and the underlaying Connection will be passed back to the pool.
      Fine!

      Now, when your JSF page iterate through the lazy list the Session will be automatically reconnected - a new Connection will be borrowed - to fetch the data from the database.

      But now, no one knows that this happened ... no one passes back this Connection to the pool.
      The request finished and the Connection is still alive in the Session.

      Its not that a big problem, though, it cost some resources especially if you have to wait until the end of a conversation to release the Connection again.


      Is there something I oversee? Do you know how to deal with?


      One solution I have in mind is a new Hibernate ConnectionReleaseMode - something like: ConnectionReleaseMode.AFTER_TRANSACTION_OTHERWISE_ALWAYS

      This means something like: If within a transaction release the connection after it, otherwise release the connection after each statement.
      Such a lazy init issued by the view will most likely be outside of any transaction ... so this could work - even if it just works with Hibernate.

      Or a way to change the ConnectionReleaseMode during the lifetime of the Session.

      Thanks!
      Ciao,
      Mario

        • 1. Re: release connection after lazy init in view
          monkeyden

          That's just the price you pay for lazy loading. That's why the option is there. For the views which require the list, just call the method to initialize. It sounds silly to me to add this "new feature" when the solution just boils down to deciding which fetch strategy works for your use case.

          • 2. Re: release connection after lazy init in view
            imario

            I think we could be able to find a solution for it. Using eager loading is one of them, though, I see three drawbacks:

            1) you have to know what the view requests from your entities - in our theoretical case where the view and the backing bean author are different persons you might not be able to know this ...

            2) you have to pollute your backing bean with database system code.
            We access the database through DAO classes, now, the same method to retrieve a list of entities has to be duplicated just to have once lazy loading or in the other case eager loading

            3) the ORM mapper looses some of its transparency

            I don't know whats "silly" on my post or my proposed solution which is just a start of a discussion.
            At least my solution keeps the ORM transparency and you have to do NOTHING in your backing bean, DAO or somewhere else in your code.

            I am sure tons of developers out there do not even know what it means having an open Connection laying around, in the worst case until the conversation times out.
            With multiple conversations (say 2 per user) and say 50 user you might end with 100 active Connections (in the worst case for sure).

            • 3. Re: release connection after lazy init in view
              imario

              Ok, looks like I found another solution/workaround.

              I provide my own Hibernate ConnectionProvider (by decorating the original one). This provider hands out so called "DisconnectableConnections" and keeps track of all borrowed/released connections.
              In a ServletFilter (at the end of the response) all not release connections will be "disconnected".
              Notice, Hibernate still holds the DisconnectableConnection and thinks everything is fine.
              One the next access via such a connection (which is "discconnected") it will be automatically reconnected.

              "disconnected" in this context simply means it has been passed back to the connection pool.

              Instead of using a ConnectionProvider one might simply decorate the connection pool itself ... but this is another story, though, it should work with any orm mapper then.