Hi Taha, That would be a reasonable place to hook it in. However, I'd like to make sure that it would work first, and it seems like in principle it's the same as the 4th way I tried (which didn't work): store the current version when the form is rendered, then when you save you grab the latest from the database but first set the version to be the version when the form was rendered. I still don't understand why that didn't work.
Donny On Sun, May 29, 2011 at 12:24 PM, Taha Hafeez <tawus.tapes...@gmail.com>wrote: > Hi Donny > > One way I can think of is extend AbstractSessionPersistentFieldStrategy as > is done by EntityPersistentFieldStrategy(tapestry-hibernate) and store > version in addition to id and type in PersistedEntity and later > while retrieving the value, check the version too > > Take a lot at > > https://svn.apache.org/repos/asf/tapestry/tapestry5/tags/releases/5.2.5/tapestry-hibernate/src/main/java/org/apache/tapestry5/internal/hibernate/EntityPersistentFieldStrategy.java > < > https://svn.apache.org/repos/asf/tapestry/tapestry5/tags/releases/5.2.5/tapestry-hibernate/src/main/java/org/apache/tapestry5/internal/hibernate/EntityPersistentFieldStrategy.java > > > > regards > Taha > > > On Sun, May 29, 2011 at 9:48 PM, Donny Nadolny <donny.nado...@gmail.com > >wrote: > > > Hi Josh, > > > > Yup, it must be. The question is, how do I stop that? I tried following > the > > example from the jumpstart demo but it didn't work, and I tried setting > the > > version field manually, and it still didn't work (the exact code I used > is > > in the initial email). > > > > On Sun, May 29, 2011 at 12:11 PM, Josh Canfield <joshcanfi...@gmail.com > > >wrote: > > > > > I would guess that you are pulling the object from the database when > you > > > post the form, and thus editing the current version. > > > > > > I believe is the default behaviour with the tapestry persistent object > > > translator, it stores the type and id in the form. > > > > > > Josh > > > On May 29, 2011 7:34 AM, "Donny Nadolny" <donny.nado...@gmail.com> > > wrote: > > > > I've got a BeanEditForm for my User entity which has a version field: > > > > > > > > @Version > > > > public long getVersion() { > > > > return version; > > > > } > > > > public void setVersion(long version) { > > > > this.version = version; > > > > } > > > > > > > > I've got an admin screen to edit a user, and I would like to make > sure > > I > > > > don't overwrite changes made by the user (they can change their > > password, > > > > for example) or by the application, while I'm on the edit screen. > I've > > > tried > > > > a few things, but I always see the same behavior: any changes in the > > > > database get overwritten when I hit "save" in the BeanEditForm. > > > > > > > > Test 1: > > > > EditUser.tml: > > > > <t:BeanEditForm object="user" t:id="editUserForm"/> > > > > > > > > EditUser.java: > > > > @CommitAfter > > > > public Object onSuccessFromEditUserForm() { > > > > return UserIndex.class; > > > > } > > > > > > > > I open the EditUser page in the browser, I change the user in the > > > database > > > > (increasing the version field by one), then I hit save in the > browser, > > > > expecting Hibernate to throw an exception. Instead, it saves the > > changes, > > > > increasing the version again. Eg I start at version 0, open the page, > > > edit > > > > the db to change a field and set version to 1, then I hit save in the > > > > browser, it clobbers my changes and sets version to be 2. > > > > > > > > > > > > Test 2: > > > > I tried out the code from JumpStart > > > > > > > > > > > > > http://jumpstart.doublenegative.com.au/jumpstart/examples/easycrud/update/2which > > > > says it handles versioning. My code now looks like this: > > > > tml: > > > > <t:BeanEditForm object="user" t:id="editUserForm"> > > > > <p:version> > > > > <t:hidden value="user.version"/> > > > > </p:version> > > > > </t:BeanEditForm> > > > > > > > > The java code is the same as Test 1. > > > > > > > > Again, the changes get clobbered. > > > > > > > > Test 3: > > > > I noticed that the hidden field didn't have an ID set, so I tried: > > > > <t:hidden value="user.version" t:id="version"/> > > > > Same thing, changes get overwritten. > > > > > > > > Test 4: > > > > Managing the version myself. In the tml I have: > > > > <t:BeanEditForm object="user" t:id="editUserForm"> > > > > <p:version> > > > > <t:hidden t:id="versionWhenLoaded"/> > > > > </p:version> > > > > </t:BeanEditForm> > > > > > > > > In java, I have: > > > > @PageActivationContext > > > > private User user; > > > > > > > > @Property > > > > private long versionWhenLoaded; > > > > > > > > public void setupRender() { > > > > versionWhenLoaded = user.getVersion(); > > > > } > > > > > > > > @CommitAfter > > > > public Object onSuccessFromEditUserForm() { > > > > user.setVersion(versionWhenLoaded); > > > > return UserIndex.class; > > > > } > > > > > > > > Again, changes get overwritten. I really would expect the last case > to > > > work > > > > - maybe I need to do something special in Hibernate to set the > version > > > > field? > > > > > > > > I'm using tapestry 5.2.4, the tapestry-hibernate dependency (so > > Hibernate > > > > 3.6.0-Final). > > > > > > > > I've confirmed that Hibernate does throw a > > > > StaleObjectStateExceptionexception when it tries to make changes to > > > > the user at the same time, by > > > > having another page which does, essentially: > > > > User user = userDAO.findById(1); > > > > timeProvider.sleep(10000); > > > > user.setFirstName("something different"); > > > > sessionManager.commit(); > > > > I load it twice, and the second page throws > StaleObjectStateException. > > > > > > > > Any ideas? > > > > > >