You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Rich M <ri...@moremagic.com> on 2011/03/22 17:39:50 UTC

BeanEditForm: What's happening to my object parameter?

Hi,

I upgraded my application to 5.2.4 and everything seemed great, but I 
eventually noticed some weird behavior regarding some functionality that 
previously worked in my application.

I have a page that displays Entities in a Grid. Each row has a link that 
triggers an event with the context of the given entity ID. At this 
point, the page stores the id in a persisted Object called PageId, and 
sets a boolean to conditionally delegate/render a sub-page in the 
template. In @BeginRender, the PageId is pushed into the environment. 
The sub-page provides a BeanEditForm for the given Entity object so a 
user can update information.

The sub-page uses @Environmental on a PageId object to grab the one 
pushed on the stack from the Grid page. In onPrepareForRender, an Entity 
object is loaded from the DB based on the value in the PageId. 
Everything is good so far. The Entity object is @Property and @Persist 
annotated. At the end of the onPrepareForRender method, the Entity is 
set properly. However, it seems to get de-referenced at some point 
between that method and AfterRender. I put a debug message in 
AfterRender and the entity object is no longer referencing the expected 
values. Strangely enough, if I define @Persist Entity entity2 and write 
entity2 = entity.clone() in the onPrepareForRender method, in 
AfterRender, entity2 is still the expected Entity object...

After some further prodding, I found out that whichever entity object is 
set as the object parameter of the BeanEditForm is being re-initialized 
as if it was assigned = new Entity(). This is breaking my page because I 
have been using the entity object to 'initialize' the BeanEditForm 
fields to the stored values of the entity. Since the entity ends up 
re-initialized during rendering, none of the previously stored fields 
are available for a user to see and edit.

What is happening to the entity object, I thought BeanEditForm was 
supposed to use it if it was an initialized property (enforced in the 
container in a "prepare" event)? The first time the Entity link is 
clicked on the GridPage, the entity object ends up null. The second time 
as well. The third time, it displays whatever the previous link should 
have displayed and continues in this fashion indefinitely. I'd assume I 
must have some flawed logic here somewhere, but it is a bit baffling 
that it used to work in 5.1.



Simplified code example:

GridPage.java

@Inject
private Environment env;
@Persist
private String subPage;
@Persist @Property
private PageId id;
@Persist @Property
private boolean subtabSelect;

public Object onActionFromDetailsLink(String cid){
         subtabSelect = true;

         this.subPage = DETAILS_TAB;
         id = new PageId(cid);
         debug("DetailsLink clicked. SubPageId set to " + this.subPage);
         ...
}

@BeginRender
     public void pushPageId(){
         debug("Loaded ViewTPTab and SubPageId = " + this.id);
         env.push(PageId.class, id);
}

@AfterRender
public void  popPageId(){
         this.id = env.pop(PageId.class);
}



DetailsTab.java:

@Environmental
     private PageId id;


     @Inject
     private Environment env;

     @Property @Persist
     private ThirdParty tp;
     @Persist
     private ThirdParty tp2;

     @Inject
     private TPDAO tpdao;

public void onPrepareForRender(){

         tp = (ThirdParty) tpdao.read(id.getId());

         /*  .... pull some info from the tp object, parse and place 
into Persisted fields. These fields are the only ones displayed properly 
in the BeanEditForm. BeanEditForm is referencing the tp object. */

         tp2 = tp.clone();
         debug("In onPrepareForRender of DetailsTab. Loaded ::"+tp+":: 
from DB");
     }

     public void afterRender(){
         debug("In afterRender... the TP object is : " + tp ); //tp is null
         debug("... tp2 : " + tp2); //tp2 = tpdao.read(id.getId())
     }

     void onPrepareForSubmit(){
         env.push(PageId.class, heldId); //push back into environment on 
submit from BeanEditForm
     }

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: BeanEditForm: What's happening to my object parameter?

Posted by Geoff Callender <ge...@gmail.com>.
Added to JIRA: https://issues.apache.org/jira/browse/TAP5-1527

On 10/05/2011, at 9:39 PM, Geoff Callender wrote:

> Nope, it's like Rich said: onPrepare() is being called twice during the render phase, and then the object disappears!
> 
> Yet, when you replace BeanEditForm with a Form around a BeanEditor it works correctly: onPrepare() is called once during the render phase and the object doesn't disappear:
> 
> 	http://jumpstart.doublenegative.com.au/jumpstart/examples/input/morecontroledit1/1
> 
> You can see the java code is almost identical in the two examples but the result is different.
> 
> Geoff
> 
> On 10/05/2011, at 8:55 PM, Geoff Callender wrote:
> 
>> It looks like a bug - onPrepare() is not being called during render of BeanEditForm. For example, this page should have rendered Person 1:
>> 
>> 	http://jumpstart.doublenegative.com.au/jumpstart/examples/input/edit1/1
>> 
>> I'm sure it worked in 5.1.0.5 but doesn't in 5.2.5.
>> 
>> Anyone else seeing this?
>> 
>> Geoff
>> 
>> 
>> On 23/03/2011, at 8:43 AM, Thiago H. de Paula Figueiredo wrote:
>> 
>>> On Tue, 22 Mar 2011 18:33:16 -0300, Rich M <ri...@moremagic.com> wrote:
>>> 
>>>>> Why don't you use onPrepare() instead of onPrepareForRender()?
>>>> Same result, unfortunately. I switched to onPrepareForRender eventually because onPrepare gets called 2-3 times during the page lifecycle while onPrepareForRender only once.
>>> 
>>> Once for rendering, once for form submits.
>>> 
>>>> In onPrepare: tp = person; name = person
>>>> In onPrepare: tp = person; name = person
>>>> tp: id = person; name = person
>>>> tp2: id = null; name = null
>>>> tp3: id = person; name = person
>>> 
>>> Strange . . .
>>> 
>>> -- 
>>> Thiago H. de Paula Figueiredo
>>> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor
>>> Owner, Ars Machina Tecnologia da Informação Ltda.
>>> http://www.arsmachina.com.br
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>> 
>> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: BeanEditForm: What's happening to my object parameter?

Posted by Geoff Callender <ge...@gmail.com>.
Nope, it's like Rich said: onPrepare() is being called twice during the render phase, and then the object disappears!

Yet, when you replace BeanEditForm with a Form around a BeanEditor it works correctly: onPrepare() is called once during the render phase and the object doesn't disappear:

	http://jumpstart.doublenegative.com.au/jumpstart/examples/input/morecontroledit1/1

You can see the java code is almost identical in the two examples but the result is different.

Geoff

On 10/05/2011, at 8:55 PM, Geoff Callender wrote:

> It looks like a bug - onPrepare() is not being called during render of BeanEditForm. For example, this page should have rendered Person 1:
> 
> 	http://jumpstart.doublenegative.com.au/jumpstart/examples/input/edit1/1
> 
> I'm sure it worked in 5.1.0.5 but doesn't in 5.2.5.
> 
> Anyone else seeing this?
> 
> Geoff
> 
> 
> On 23/03/2011, at 8:43 AM, Thiago H. de Paula Figueiredo wrote:
> 
>> On Tue, 22 Mar 2011 18:33:16 -0300, Rich M <ri...@moremagic.com> wrote:
>> 
>>>> Why don't you use onPrepare() instead of onPrepareForRender()?
>>> Same result, unfortunately. I switched to onPrepareForRender eventually because onPrepare gets called 2-3 times during the page lifecycle while onPrepareForRender only once.
>> 
>> Once for rendering, once for form submits.
>> 
>>> In onPrepare: tp = person; name = person
>>> In onPrepare: tp = person; name = person
>>> tp: id = person; name = person
>>> tp2: id = null; name = null
>>> tp3: id = person; name = person
>> 
>> Strange . . .
>> 
>> -- 
>> Thiago H. de Paula Figueiredo
>> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor
>> Owner, Ars Machina Tecnologia da Informação Ltda.
>> http://www.arsmachina.com.br
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: BeanEditForm: What's happening to my object parameter?

Posted by Geoff Callender <ge...@gmail.com>.
It looks like a bug - onPrepare() is not being called during render of BeanEditForm. For example, this page should have rendered Person 1:

	http://jumpstart.doublenegative.com.au/jumpstart/examples/input/edit1/1

I'm sure it worked in 5.1.0.5 but doesn't in 5.2.5.

Anyone else seeing this?

Geoff


On 23/03/2011, at 8:43 AM, Thiago H. de Paula Figueiredo wrote:

> On Tue, 22 Mar 2011 18:33:16 -0300, Rich M <ri...@moremagic.com> wrote:
> 
>>> Why don't you use onPrepare() instead of onPrepareForRender()?
>> Same result, unfortunately. I switched to onPrepareForRender eventually because onPrepare gets called 2-3 times during the page lifecycle while onPrepareForRender only once.
> 
> Once for rendering, once for form submits.
> 
>> In onPrepare: tp = person; name = person
>> In onPrepare: tp = person; name = person
>> tp: id = person; name = person
>> tp2: id = null; name = null
>> tp3: id = person; name = person
> 
> Strange . . .
> 
> -- 
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor
> Owner, Ars Machina Tecnologia da Informação Ltda.
> http://www.arsmachina.com.br
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: BeanEditForm: What's happening to my object parameter?

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Tue, 22 Mar 2011 18:33:16 -0300, Rich M <ri...@moremagic.com> wrote:

>> Why don't you use onPrepare() instead of onPrepareForRender()?
> Same result, unfortunately. I switched to onPrepareForRender eventually  
> because onPrepare gets called 2-3 times during the page lifecycle while  
> onPrepareForRender only once.

Once for rendering, once for form submits.

> In onPrepare: tp = person; name = person
> In onPrepare: tp = person; name = person
> tp: id = person; name = person
> tp2: id = null; name = null
> tp3: id = person; name = person

Strange . . .

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: BeanEditForm: What's happening to my object parameter?

Posted by Rich M <ri...@moremagic.com>.
On 03/22/2011 05:10 PM, Thiago H. de Paula Figueiredo wrote:
> On Tue, 22 Mar 2011 17:53:12 -0300, Rich M <ri...@moremagic.com> wrote:
>
>> Okay, maybe I'm not interpreting the page lifecycle properly here, or 
>> it has changed it some way that is causing me problems? The entity is 
>> referenced and loaded properly in onPrepareForRender. Considering 
>> that BeanEditor only changes the value of the edited property if it's 
>> null, then what could be causing the private entity field to become 
>> set to null between onPrepareForRender and the coupling/rendering of 
>> the BeanEditor? I have no direct statements doing as much in my code.
>
> Why don't you use onPrepare() instead of onPrepareForRender()?
Same result, unfortunately. I switched to onPrepareForRender eventually 
because onPrepare gets called 2-3 times during the page lifecycle while 
onPrepareForRender only once. It didn't break anything back in 5.1.0.15 
so it seemed like a good idea. I wanted to avoid extra DB calls and 
array/String parsing. On another note, I'm not sure whether this problem 
even relates to the @Environmental object at all, but I did figure I'd 
mention it before just in case.

Anyway, here is what is happening:

@Property @Persist
private ThirdParty tp;
@Persist @Property
private ThirdParty tp2;
@Persist
private ThirdParty tp3;

public void onPrepare(){
     ThirdParty tp = tpdao.read( id.getId() );

     // perform field parsing for overridden BeanEditForm blocks

     ThirdParty tp2 = tp.clone();
     ThirdParty tp3 = tp.clone();

     log.debug("In onPrepare: tp = " + tp);
}

public void afterRender(){
     log.debug("tp: " + tp + "\n tp2: " + tp2 + "\n tp3: " + tp3);
}

TML:
<t:beaneditform object="tp2">

Results:

In onPrepare: tp = person; name = person
In onPrepare: tp = person; name = person
tp: id = person; name = person
tp2: id = null; name = null
tp3: id = person; name = person


>
>> In response to the Environment vs. Component Parameters, these are 
>> all Pages not Components. Actually this structure and exact use was 
>> discussed in this ( 
>> http://tapestry.markmail.org/thread/4rffky2r2uqno5ea#query:+page:1+mid:j375h7obo6hd2i6b+state:results 
>> ) previous thread.
>
> I remember that. :) Yep, you need the Environment here.
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: BeanEditForm: What's happening to my object parameter?

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Tue, 22 Mar 2011 17:53:12 -0300, Rich M <ri...@moremagic.com> wrote:

> Okay, maybe I'm not interpreting the page lifecycle properly here, or it  
> has changed it some way that is causing me problems? The entity is  
> referenced and loaded properly in onPrepareForRender. Considering that  
> BeanEditor only changes the value of the edited property if it's null,  
> then what could be causing the private entity field to become set to  
> null between onPrepareForRender and the coupling/rendering of the  
> BeanEditor? I have no direct statements doing as much in my code.

Why don't you use onPrepare() instead of onPrepareForRender()?

> In response to the Environment vs. Component Parameters, these are all  
> Pages not Components. Actually this structure and exact use was  
> discussed in this (  
> http://tapestry.markmail.org/thread/4rffky2r2uqno5ea#query:+page:1+mid:j375h7obo6hd2i6b+state:results  
> ) previous thread.

I remember that. :) Yep, you need the Environment here.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: BeanEditForm: What's happening to my object parameter?

Posted by Rich M <ri...@moremagic.com>.
On 03/22/2011 02:50 PM, Thiago H. de Paula Figueiredo wrote:
> Hi!
>
> BeanEditor, which is used inside BeanEditForm, only changes the value 
> of the edited property if it's null, so the problem should be 
> elsewhere. By the way, why are you using the Environment instead of 
> component parameters? And what do you call a subpage?
>
Okay, maybe I'm not interpreting the page lifecycle properly here, or it 
has changed it some way that is causing me problems? The entity is 
referenced and loaded properly in onPrepareForRender. Considering that 
BeanEditor only changes the value of the edited property if it's null, 
then what could be causing the private entity field to become set to 
null between onPrepareForRender and the coupling/rendering of the 
BeanEditor? I have no direct statements doing as much in my code.

In response to the Environment vs. Component Parameters, these are all 
Pages not Components. Actually this structure and exact use was 
discussed in this ( 
http://tapestry.markmail.org/thread/4rffky2r2uqno5ea#query:+page:1+mid:j375h7obo6hd2i6b+state:results 
) previous thread. In trying to mentally recall the justification, I 
believe the intent is that there is a two-way relationship on the 
@Environmental PageId id between the container page and the 'subpage'. 
The subpage term here means that there is the container page with the 
Grid, and then the subordinate page (loaded via Delegate in container) 
with the BeanEditForm. By two-way relationship, I mean that the GridPage 
can manipulate the PageId so that a SubPage can load the correct Entity, 
and going the other way, the SubPage can reset the PageId in the 
environment in the event that the user deletes the Entity so the 
GridPage is aware.

Maybe I just need to completely re-evaluate my approach here, perhaps my 
prior implementation worked by miracle rather than design (I've been 
forced to learn and seriously develop Tapestry concurrently. 
Component-driven design over Page-driven design wasn't quite in my 
repertoire back in August). Before I invest time into that though, I 
want to verify that there isn't some easy adjustment to my existing code 
to restore functionality.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: BeanEditForm: What's happening to my object parameter?

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Hi!

BeanEditor, which is used inside BeanEditForm, only changes the value of  
the edited property if it's null, so the problem should be elsewhere. By  
the way, why are you using the Environment instead of component  
parameters? And what do you call a subpage?

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org