Thanks for all the comments. They've been invaluable. Below is the result, Mark Vi.

Kalle, I'm using T5.0.9, but I think 5.0.7 would behave similarly. Yes, I'm trying frantically to keep up with the releases!

As Davor pointed out, if validation has failed then getting the entity again doesn't overwrite the form in recent releases. I believe, however, that this only works if you keep everything that can fail in the onValidate... methods, eg. changePerson is called in onValidateFromForm instead of in onSuccess for this very reason.

As Martin pointed out, I can avoid getting the entity every time in onActivate if I use @Persist("flash"), test for null entity in onActivate, and nullify "flash" fields in cleanupRender, ie. right before the page is displayed. The reason for the last bit is that sometimes there's only one onActivate before a page is displayed, so an attempt to refresh the page won't work because the entity is still in flash-persistence. A second attempt would work, which is very disconcerting.

Davor, I like Martin's cleanupRender effect, so I don't think the "new window" problems you describe occur, and therefore I don't think I need the @Meta form annotation. Have I missed a corner-case here?

If you're using BeanEditForm, just replace "Form" with "BeanEditForm".

        private Long _personId;

        @Persist("flash")
        private Person _person;

        @Component(id = "form")
        private Form _form;

        @InjectPage
        private NextPage _nextPage;

        void onActivate(Long id) throws Exception {
                _personId = id;
                if (_person == null) {
                        _person = getPersonService().findPerson(_personId);
                }
        }

        Long onPassivate() {
                return _personId;
        }

        void onValidateFromForm() {
                if (...a bit of validation logic detects an error...) {
                        _form.recordError(...);
                        return;
                }
// todo: move this next block back to onSuccess() once TAPESTRY-1972 has been resolved.
                try {
                        getPersonService().changePerson(_person);
                }
                catch (Exception e) {
                        _form.recordError(ExceptionUtil.getRootCause(e));
                }
        }

        Object onSuccess() {
                _nextPage.onActivate(_personId);
                return _nextPage;
        }

        void cleanupRender() {
                _form.clearErrors();
// Clear the flash-persisted fields to prevent anomalies in onActivate when we hit refresh on page or browser button
                _person = null;
        }

and of course the hidden version field stuff still applies (it ensures optimistic locking works, preventing us saving changes to a Person that has since been updated or deleted by someone else or by us in another of our windows or tabs):

                <t:hidden t:id="version" value="person.version"/>

or if you're using BeanEditForm:

        <t:beaneditform t:id="form" object="person" submitLabel="Save">
                <t:parameter name="version">
                        <t:hidden t:id="version" value="person.version"/>
                </t:parameter>
        </t:beaneditform>

Any more thoughts?

Geoff

Reply via email to