|
From: <jue...@we...> - 2004-05-19 23:12:32
|
Daniel, =20 The problem that you indicate occurs when you bind request parameters to = a *freshly loaded* Hibernate object in combination with the Open Session = in View pattern. However, that sort of binding is not the typical case; = do you have a concrete use case for it? =20 Typically, you will load a Hibernate object for displaying a form first. = On submission (in a separate request), the object will be taken from the = HttpSession and populated with request parameters. In that case, the = Hibernate object is not registered with an active Hibernate Session = anymore, therefore changes to it won't get persisted. Only after = successful submission of the form, you will explicitly reassociate such = an object with a Hibernate Session - and only then the changes will get = persisted. =20 So for the typical form case, the Open Session in View pattern should = not cause such side effects. And of course, if you don't use the Open = Session in View pattern in the first place, you'll *never* have such = side effects. =20 If I missed your point, please tell me :-) =20 Juergen =20 ________________________________ Von: spr...@li... im Auftrag = von Daniel Miller Gesendet: Mi 12.05.2004 04:39 An: Springframework-Developer@Lists. Sourceforge. Net Betreff: [Springframework-developer] Pre-binding validation Recently while browsing the Help list (man do I still have a life or = not?) I came across this post: https://sourceforge.net/forum/message.php?msg_id=3D2564738 It got me thinking about a potential problem with Spring MVC. Spring MVC allows the user to bind the submit request directly to a persistent = object (assume that the command object has been loaded using a Hibernate DAO in formBackingObject()). This eliminates a lot of code needed to transfer = data from the form (i.e. Struts ActionForm) to the persistent object. However there is a potential problem here: All data that does not trigger binding failure is bound directly to the persistent object _before_ validation. If I understand the thread local session pattern correctly, any transactional method call that performs a flush after this point will = cause Hibernate to collect all of the persistent objects that it knows about = (all objects in the current session) and update the database with the = contained values. <quote reference=3D"hibernate_reference.pdf" chapter=3D"8.4"> Persistent instances (ie. objects loaded, saved, created or queried by = the Session) may be manipulated by the application and any changes to = persistent state will be persisted when the Session is flushed (see "flushing" = below). So the most straightforward way to update the state of an object is to load() it, and then manipulate it directly. </quote> and the relevant section on flushing: <quote reference=3D"hibernate_reference.pdf" chapter=3D"8.9"> >From time to time the Session will execute the SQL statements needed to synchronize the JDBC connection's state with the state of objects held = in memory. This process, flush, occurs by default at the following points * from some invocations of find() or iterate() * from net.sf.hibernate.Transaction.commit() * from Session.flush() </quote> Very sneaky, we don't even need to call update(persistent_object) to get = our object persisted. At this point, Spring invokes a validator with the persistent object as = its subject. If there are errors, the user will be forwarded back to the = form. However, the database could be in an inconsistent state because any = value that was successfully bound to the persistent object could possibly = already have been persisted to the database due to some unrelated transactional method call. Please point out my error(s) here if I have made one or many. One potential solution (inspired by above mentioned post): Create a RequestWrapper that can be validated just like the persistent object to which the request will be bound (I realize this could be messy because it is essentially reverse reflection aka emulation). Then invoke = the validator substituting the wrapped request for the actual object = _before_ binding. Feedback is greatly appreciated. Thanks. Daniel Miller ------------------------------------------------------- This SF.Net email is sponsored by Sleepycat Software Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver higher performing products faster, at low TCO. http://www.sleepycat.com/telcomwpreg.php?From=3Dosdnemail3 _______________________________________________ Springframework-developer mailing list Spr...@li... https://lists.sourceforge.net/lists/listinfo/springframework-developer |