Hi Taha,

Nice find, that's exactly the problem I have. Unfortunately it didn't seem
to work. I've tried:
tml:
    <t:BeanEditForm object="user" t:id="editUserForm">
        <p:version>
            <t:hidden t:id="versionWhenLoaded"/>
        </p:version>
    </t:BeanEditForm>
java:
    public void setupRender() {
        versionWhenLoaded = user.getVersion();
    }
    public void onPrepareEditUserForm() {
        session.clear();
    }
    @CommitAfter
    public Object onSuccessFromEditUserForm() {
        user.setVersion(versionWhenLoaded);
        return UserIndex.class;
    }

Didn't work. also tried merge:
tml: same as above
    @CommitAfter
    public Object onSuccessFromEditUserForm() {
        user.setVersion(versionWhenLoaded);
        session.merge(user);
        return UserIndex.class;
    }

Again, it just overwrites the changes.

This is a hibernate issue, but it would be nice if Tapestry's BeanEditForm
had an option (maybe even the default?) for proper handling of columns
marked with @Version. I think I'll open an issue for it.

Donny

On Sun, May 29, 2011 at 12:59 PM, Taha Tapestry <tawus.tapes...@gmail.com>wrote:

> Check this out
>
> https://forum.hibernate.org/viewtopic.php?f=1&t=957807
>
> Sent from my iPhone
>
> On May 29, 2011, at 10:06 PM, Donny Nadolny <donny.nado...@gmail.com>
> wrote:
>
> > 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?
> >>>>
> >>>
> >>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>

Reply via email to