Agree.
And even on presentation layer OSIV fails.
Re:OSIV & <redirect/>
Agree.
And even on presentation layer OSIV fails.
Re:OSIV & <redirect/>
Spring, it's a wonderful thing...
I'm not using it at the moment, I'm not really planning to use it, but it's nice it's there should I ever decide to. It's not really that hard to know what you want and ensure it's loaded. I have seen people taking lazy loading for granted a little too much with OSIV and ending up with performance issues. I think I'll stick with eager loading.
There is another issue with OSIV that hasn't been discussed in this thread yet. What do people think?
To implement OSIV it is common to set the flush mode to FlushMode.MANUAL (e.g. this is the default behaviour of the Spring OSIV helpers). The rational for this is that your service layer will have transaction boundaries,and you want to flush at the end of a transaction to preserve TX semantics. A side effect is that you lose transactional rigour - the contents of the session are not guaranteed to be synchronized with the database. E.g. if you change the value of a persistent property, and then do a query for objects of the same type, the change you made is not taken into account (there's no chance for Hibernate to flush the change before the query).
It's interesting that the Hibernate crowd now seem to be recommending Open Session In Conversation (c.f. Bauer and King's latest book, and their promotion of Seam), whereas historically I believe they and others were pretty lukewarm about it. OSIC suffers from the same lack of transactional rigour but in spades, because a conversation is much longer than a request.
Personally I am still quite attracted to both patterns for reasons of productivity (basically the same point made already about tight coupling between the service layer and views). Generally the lack of transactional rigour is only going to bite you infrequently, whereas lazy-loading is orders of magnitude more efficient than trying to deal with the tight coupling.
Note that the POST-redirect-GET issue pointed out by Arno goes away with OSIC. PRG is such a godsend it makes OSIC an very interesting technique irrespective of some other problems.
But, one problem with OSIC inprinciple is that I actually usually *want* to be working with detached objects in the web layer. It sounds perverse, but that is one good way to ensure that changes are not flushed to the database before the user decides that they are ready. I guess you get round that by ending a conversation in a special way if the user cancels out, but I haven't seen that in any discussions of OSIC I have read.
There is also the old chestnut of entity identity and not knowing the id until you have done an insert. If I delay the insert until the end of the conversation or view I must use a special class of id generator. This also exposes the lack of transactional rigour quite starkly: if the object I am working with is not in the database until the end of the session it can never be returned by any queries.
The alternative to delayed inserts and FlushMode.MANUAL is compensating deletes to cancel an insert that wasn't required, and compensating updates to cancel changes that weren't required. Everything has to be undo-able, the audit trail makes no sense (if there is one), and the implementation is much more complex again - probably even worse than the tight coupling between service and view discussed earlier.
I think part of the problem with OSIV, is the lack of 'in your face' documentation. Someone told me a few weeks ago the information on the JavaDoc had put him off using it. He didn't actually really understand the full implications of what using it meant. I did actually JIRA the the lack of information a while ago, I'm not sure where it's currently at.
http://www.springframework.org/docs/...iewFilter.html
You raise some really interesting points David, which might be worthy of a thread or blog of it's own? What are the complete implications of OSIV? What do are the drawbacks? I'm sure this is a question that lots of people would like some clarity on. I know it's on the list of potential FAQs!!
I'll work it up into a blog when I get time. There is actually quite a bit of reading matter in Bauer and King's newest book. I find the index a bit frustrating because you have to chase around a bit to find all the entries. Of course they don't mention how to implement the patterns with Spring (hint: use SessionFactoryUtils.*DeferredClose methods.)
There have been a good number of posts regarding this, it would be nice to have somewhere to point people at. I'd be quite interested to hear your thoughts as well! I have heard good things about the new book. It's been on my huge list of things to do for a while now. Hibernate in Action was pretty good, so hopefully it won't be a disappointment. The lack of Spring coverage is a little disappointing, but not really unexpected.
We use OpenSessionInView in our project. Main reasons were rich domain model and use of detached objects. Another twist was that our GUI can be reconfigured by the customer once product is installed. Our default screens are pretty heavy (tons of accounting info) and can be changed depending on user's security profile or what customer wants to see on their screens. So instead of building some smarts into the service where it will take some sort of meta data about the view and materialize/initialize all detached objects before returning to the view we opted to use OSIV. Performance improvements were great. Update logic had to be tweaked a bit where detached objects need to be reattached to the session in the beginning of the service.
I would be happy to provide more details if anyone wants.
Vitaliy
how do you reattach an object? getSession().refresh(object) is that the right call? does that actually hit the database?
refresh will reload object from the database and wipe out your changes.
We do update. It may hit database if you are using identity columns. I.e. you are passing detached parent object with new children. If you are using sequence the call will be delayed till flush (as far as I remember.)
You could also look at merge() or saveOrUpdate().
http://www.hibernate.org/hib_docs/v3...a.lang.Object)
http://www.hibernate.org/hib_docs/v3...a.lang.Object)