Announcement Announcement Module
Collapse
No announcement yet.
Why OpenSessionInViewFilter is misleading and useless in most cases Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Why OpenSessionInViewFilter is misleading and useless in most cases

    I might be wrong but this is my understanding.

    There has been so much discussion about this Pattern but I'm surprised to see how blogs and articles embrace this pattern as if it's a panacea to solve lazy load exception of Hibernate. (and everything else). The ironic reality is OSIV works only within a request.

    Yes, A single Request.

    Consider this example.

    User has a Tree model with nodes, children in the view or a single complex form which need to dynamically load associations based on user triggers. If you're using Spring MVC, this entire object could be your command object and is stored on HttpSession as well. Typically what the user wants is to load the object once and based on the user interaction, on a need-basis, load the collection objects. But as this is going to be another request each time, a new Hibernate Session is created, perhaps wrapped under a transaction and you get LazyInitialiationException as it is now two different Sessions.

    As long as your lazy associations get initialized within the original transaction, there is no need to perform lazy loading in your views.
    And if you anyway wanted to see all collections in the first request itself, why do you need to set lazy=true and add OSIV in the first place? (It's as good as having lazy=false). The point is, I think "lazy=true" is inherently designed for larger use cases which almost involve multiple http requests. OSIV is misleading in this respect that it doesn't serve the purpose. Not only that - the terms 'single session mode' and 'deferred close' add more confusion to the developers as they don't necessarily add a new feature but merely do not open a session but close all sessions in the sessionFactory registered as deferred. Probably helps if you want multiple sessions in a transaction. But then, it still works withing a SINGLE request

    I'm still yet to see a blog or article on these forums on how anyone has solved this problem. Detached Criteria? Reattaching objects sounds cool but anyone has a working code generic enough to make it a pattern or a template method for the controllers?

    Would like to know if somebody shares my views too and what is the right approach to solve this. An idea similar to OpenSessionInFlow would help

    PS: Going by the name, I think it should be called "OpenSessionInRequest" , I'd buy that!
    Last edited by infinity2heaven; Jul 18th, 2007, 11:43 PM.

  • #2
    I agree with your use case of maintaining a complex object in the session, and working with it through a series of pages doesn't fit with OSIV, however I think OSIV is meant to solve a different type of problem.
    As long as your lazy associations get initialized within the original transaction, there is no need to perform lazy loading in your views.
    IMO this is exactly the problem that OSIV is meant to solve. In many cases, especially with extremely dense and complex object structures, you don't want to have to explicitly initialize entire subtrees when they may not be used in a particular view. OSIV allows lazy loading of collections to work as expected, that is, collections are loaded when they are used and not sooner.

    That said, the use of OSIV does break some tenets of separation of concerns and really breaks transactional semantics if you're using TX interceptors below the controller level of your Spring MVC app.
    I'm surprised to see how blogs and articles embrace this pattern as if it's a panacea to solve lazy load exception of Hibernate. (and everything else).
    I actually had thought that OSIV was not recommended because it can potentially cause problems with separation of concerns, as I mentioned. Reliance on OSIV can also make it hard to match up non-web-based unit tests with actual functionality in the web-based application.

    As I said, I do agree that what you're describing would be useful, but I don't see why you can't get the functionality you're describing by reattaching the session-based object in formBackingObject (or in the appropriate method if you're using a wizard controller).

    Comment


    • #3
      but I don't see why you can't get the functionality you're describing by reattaching the session-based object in formBackingObject (or in the appropriate method if you're using a wizard controller
      I've used a customized Wizard controller before and temporarily solved it (bad hack) but loading all collections in individual dao but doing a .size() on each child). But this scenario is not necessarily limited to a "page flow". Like I've mentioned, it could be a datastructure like Tree with rich set of objects under it, say on the left side of a view. What do you think the right pattern is, in this case? And if we bring in communication between this structure along with form elements( say a form on the right side of the view which displays the attributes of the object selected), things get really messy while manipulating detached objects with newly loaded objects.

      What I am looking for is a generic solution (if any) to solve this rather typical use case along with OSIV as I still would like to have it for it's limited solutuion.

      Saying "use detached criteria ...there" sounds simple on paper until someone has actually implemented this over a large set of use cases.

      Any suggestions?

      Comment


      • #4
        Originally posted by pmularien View Post
        OSIV allows lazy loading of collections to work as expected, that is, collections are loaded when they are used and not sooner.
        But probably not the collection at once. Another downside of OSIV is the tend to initialize object by object in the collection which can extremely slow down the application if you don't take care.

        Jörg

        Comment


        • #5
          Not sure if I quite understand your statement. Could you be more specific?

          Comment


          • #6
            You iterate over the collection of non-initialized objects. For each object there is one database statement done. Something like "select * from table where id=1" and so on instead of once just "select * from table".

            Jörg

            Comment


            • #7
              Commonly referred to as the "N+1 selects" issue.

              Comment


              • #8
                Thats a surprise! I didn't know that OSIV simulates a N+1 selects problem and it isn't apparent from Hibernate's reference either.

                Comment


                • #9
                  That's one of the reasons I'm not a huge fan of OSIV, it's seductively easy to get up and running and you never have to worry about loading the entities within that request. This means you get away without thinking about the issues involved.
                  Last edited by karldmoore; Aug 27th, 2007, 04:08 PM.

                  Comment


                  • #10
                    Hey karldmoore, you're back again., interesting to see that you've added another 3000 posts since the last time we spoke!

                    I still am waiting for reply in this thread for a recommended pattern for the use case given in the original post. (lazyload, multiple requests - a generic solution)

                    PS: Hope this thread doesn't turn out to be a zombie like all the other OSIV threads
                    Last edited by infinity2heaven; Jul 20th, 2007, 12:46 PM.

                    Comment


                    • #11
                      Originally posted by Jörg Heinicke View Post
                      You iterate over the collection of non-initialized objects. For each object there is one database statement done. Something like "select * from table where id=1" and so on instead of once just "select * from table".

                      Jörg
                      This can be mitigated with adjustments to hibernate settings, IIRC.

                      Comment


                      • #12
                        This can be mitigated with adjustments to hibernate settings, IIRC
                        Would appreciate more info on this ...

                        Comment


                        • #13
                          Originally posted by infinity2heaven View Post
                          Hey karldmoore, you're back again., interesting to see that you've added another 3000 posts since the last time we spoke!
                          Has it been that long .

                          Originally posted by infinity2heaven View Post
                          I still am waiting for reply in this thread for a recommended pattern for the use case given in the original post. (lazyload, multiple requests - a generic solution)
                          The concept of a flow and therefore OpenSessionInFlow seems to be a good idea to me. You basically want to keep the Session open for the lifetime of the flow, therefore defering closing the Session until you've finished what you were doing.

                          Originally posted by infinity2heaven View Post
                          PS: Hope this thread doesn't turn out to be a zombie like all the other OSIV threads
                          Have you tried the Hibernate forums, there might be more information there.
                          Last edited by karldmoore; Aug 27th, 2007, 04:08 PM.

                          Comment


                          • #14
                            Originally posted by infinity2heaven View Post
                            Would appreciate more info on this ...
                            Hibernate fetching strategies.

                            Typically I use subselect fetching.

                            Regarding OSIV; my beef is mostly with regards to the inability to re-attach an object to the new session. As a result, binding must occur against a new object (retrieved from the database) because you cannot bind against the object you got in the previous request. Reason being, you'll be unable to persist that object as it's still tied to the previous session which has since been closed. Not only is this useless overhead, but it creates all sorts of problems when you'd like to take advantage of things like hibernate versioning for example.

                            Comment


                            • #15
                              Originally posted by jglynn View Post
                              Commonly referred to as the "N+1 selects" issue.
                              Oh, thanks for the name. Might simplify explanation the next time :-)

                              Jörg

                              Comment

                              Working...
                              X