RE: Best practice for new/edit object page?
Quick update on this: If you're persisting the ID of an entity so you don't have to embed it in the page (the main conclusion from this thread), the pseudocode I used before with regard to the pageBeginRender implementation has two potential gotchas in it (found so far). To refresh, I said: "Have your page implement the PageBeginRenderListener, and in your pageBeginRender method, if the ID is not null, "get" the object (I'm using Hibernate semantics) if you're not rewinding, and "load" the object if you are." First, if you're using Hibernate semantics, you'll probably want to "get" the entity either way, or you'll likely get a LazyInitializationException depending on what you've OGNL-mapped. Second, if you're using validation, you need to be careful not to re-query the object out when rendering after a validation error. Consider the order: 1. Submit the form 2. pageBeginRender(rewind) - queries out object 3. rewind - sets mapped-form-properties to object 4. validation - finds error 5. listener - since there were validation errors, returns "this" 6. pageBeginRender(render) - queries out object 7. renders with persisted properties, not the invalid inputs <-- problem New pseudo-pseudocode for pageBeginRender: ... if (getValidationDelegate().getHasErrors()) { if (id != null) { setEntity(getEntityService().get(id)); } else { setEntity(new Entity()); } } ... i.e. If there were errors, you'll want to render the page with the data that was entered. Jim - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: Best practice for new/edit object page?
No, that's perfect! Properties we don't want to be changed, we're not exposing to the template at all, because that makes us vulnerable to the user spoofing new values for those properties, even if they're hidden. So, in pageBeginRender(..), we load the object we want to update, and then in Tapestry's rewind phase, only those properties that were bound to the form are set (and marked dirty), so then in the listener, only those properties that were actually exposed to the user-interface are actually ultimately updated by Hibernate. Meanwhile, no EJB transfer objects ^_^ Jim -Original Message- From: Jesse Kuhnert [mailto:[EMAIL PROTECTED] Sent: Monday, July 10, 2006 2:50 PM To: Tapestry users Subject: Re: Best practice for new/edit object page? No that's true, hibernate will only update members that have changed. They modify all of your classes with cglib to add changing listeners to fields/values. (Also how you get lazy initialization). There are still some issues with this though as the current logic in tapestry wrt forms would be that all values get re-parsed on submission and set on your object..Making hibnerate think that you may have changed all of them. (Any members bound to specific form fields at least). On 7/10/06, Jim Steinberger <[EMAIL PROTECTED]> wrote: > > "If the user enters the edit page for an existing item and then clicks > the link to create a new item I will have to reset the ID, am I right? > My current PageLink will not do in that case." > > Right; I'm using DirectLinks in both cases, setting the ID to be either > the appropriate ID or NULL if I'm creating a brand new object. > > > One last thought ... that synchronization issue I mentioned ... that > might be even /further/ mitigated if using Hibernate, since I'm pretty > sure that even even for detached objects, Hibernate will maintain which > properties of a loaded object have been modified (i.e. "dirty" flags), > and will only update those properties. i.e. if the user-interface is > only modifying properties A and B, depending on your setup, Hibernate > might only update A and B, and not C and D. This begs for a proper > test, though. > > Jim > > -Original Message- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf > Of Malin Ljungh > Sent: Monday, July 10, 2006 2:23 PM > To: Tapestry users > Subject: Re: Best practice for new/edit object page? > > Thank you. Especially Jim, you have understood my "problem" perfectly! > The thing is I have a hibernate OR-mapping with lots of relationships > and > attributes which the user should not edit or see at all in the edit > page. > > I think I'll use your #3 - keeping the ID in the session using @Persist > and > reload entity from database at postback. > My wonder is then - how do I detect the "new entity" scenario? If the > user > enters the edit page for an existing item and then clicks the link to > create > a new item I will have to reset the ID, am I right? My current PageLink > will > not do in that case. > > Malin > > On 7/10/06, Jim Steinberger <[EMAIL PROTECTED]> wrote: > > > > Hi Malin, > > > > Here are my thoughts: > > > > 1. Embedding the ID into the page (along with every other property of > > the entity). > > > > Benefit: After the rewind phase sets all the OGNL-mapped properties to > > your page-property-object, you can simply pass that object directly to > > the service/persistence layers to be saved. > > > > Downside: This only works if you're comfortable embedding all of the > > object's properties in the page. There's a security issue here (if > it's > > not an SSL connection, for example, you wouldn't want a user's > password > > or social security number being transferred in cleartext). There's a > > practicality issue, too; if your object has a lot of associated > > entities, it'd probably be too cumbersome to embed the entire > > object-graph inside the page. > > > > > > 2. Embedding the ID into the page (along with, only, properties you > > intend to be updatable) > > > > Downside: I don't know of a great way to do this. As you asked: " but > > this means I will have to redo EventServices.getEvent(eventId) after > > postback. This could maybe be OK but where do I put the code?" After > > all, you need the ID in order to query out the object, but that ID > isn't > > set via OGNL until after the rewind phase. The problem here, then, is > > that you'd have to manually set all the properties to the object in > your > > listener.
Re: Best practice for new/edit object page?
No that's true, hibernate will only update members that have changed. They modify all of your classes with cglib to add changing listeners to fields/values. (Also how you get lazy initialization). There are still some issues with this though as the current logic in tapestry wrt forms would be that all values get re-parsed on submission and set on your object..Making hibnerate think that you may have changed all of them. (Any members bound to specific form fields at least). On 7/10/06, Jim Steinberger <[EMAIL PROTECTED]> wrote: "If the user enters the edit page for an existing item and then clicks the link to create a new item I will have to reset the ID, am I right? My current PageLink will not do in that case." Right; I'm using DirectLinks in both cases, setting the ID to be either the appropriate ID or NULL if I'm creating a brand new object. One last thought ... that synchronization issue I mentioned ... that might be even /further/ mitigated if using Hibernate, since I'm pretty sure that even even for detached objects, Hibernate will maintain which properties of a loaded object have been modified (i.e. "dirty" flags), and will only update those properties. i.e. if the user-interface is only modifying properties A and B, depending on your setup, Hibernate might only update A and B, and not C and D. This begs for a proper test, though. Jim -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Malin Ljungh Sent: Monday, July 10, 2006 2:23 PM To: Tapestry users Subject: Re: Best practice for new/edit object page? Thank you. Especially Jim, you have understood my "problem" perfectly! The thing is I have a hibernate OR-mapping with lots of relationships and attributes which the user should not edit or see at all in the edit page. I think I'll use your #3 - keeping the ID in the session using @Persist and reload entity from database at postback. My wonder is then - how do I detect the "new entity" scenario? If the user enters the edit page for an existing item and then clicks the link to create a new item I will have to reset the ID, am I right? My current PageLink will not do in that case. Malin On 7/10/06, Jim Steinberger <[EMAIL PROTECTED]> wrote: > > Hi Malin, > > Here are my thoughts: > > 1. Embedding the ID into the page (along with every other property of > the entity). > > Benefit: After the rewind phase sets all the OGNL-mapped properties to > your page-property-object, you can simply pass that object directly to > the service/persistence layers to be saved. > > Downside: This only works if you're comfortable embedding all of the > object's properties in the page. There's a security issue here (if it's > not an SSL connection, for example, you wouldn't want a user's password > or social security number being transferred in cleartext). There's a > practicality issue, too; if your object has a lot of associated > entities, it'd probably be too cumbersome to embed the entire > object-graph inside the page. > > > 2. Embedding the ID into the page (along with, only, properties you > intend to be updatable) > > Downside: I don't know of a great way to do this. As you asked: " but > this means I will have to redo EventServices.getEvent(eventId) after > postback. This could maybe be OK but where do I put the code?" After > all, you need the ID in order to query out the object, but that ID isn't > set via OGNL until after the rewind phase. The problem here, then, is > that you'd have to manually set all the properties to the object in your > listener. > > > 3. Keeping the ID in the session > > Implementation: Instead of setting the ID to the visit object (or > another application-state-object), declare the ID as a property of the > page, and also declare it to be persistent (e.g. the @Persist > annotation). Have your page implement the PageBeginRenderListener, and > in your pageBeginRender method, if the ID is not null, "get" the object > (I'm using Hibernate semantics) if you're not rewinding, and "load" the > object if you are. If you're rewinding, then, you'll query out the > object as it currently appears in the database, and then the rewind > phase will set all the OGNL mapped properties to it (which are the only > ones you intend to be mutable). You can then pass this to the > service/persistence layer in your listener. > > Downside: Very slight RAM overhead (I try to avoid persistent > properties/session data as much as possible, but individual Integer > objects should take awhile to add-up [I say perhaps naively]). > > Benefit: Only the properties intended to be edited will be sent to the > client. >
RE: Best practice for new/edit object page?
"If the user enters the edit page for an existing item and then clicks the link to create a new item I will have to reset the ID, am I right? My current PageLink will not do in that case." Right; I'm using DirectLinks in both cases, setting the ID to be either the appropriate ID or NULL if I'm creating a brand new object. One last thought ... that synchronization issue I mentioned ... that might be even /further/ mitigated if using Hibernate, since I'm pretty sure that even even for detached objects, Hibernate will maintain which properties of a loaded object have been modified (i.e. "dirty" flags), and will only update those properties. i.e. if the user-interface is only modifying properties A and B, depending on your setup, Hibernate might only update A and B, and not C and D. This begs for a proper test, though. Jim -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Malin Ljungh Sent: Monday, July 10, 2006 2:23 PM To: Tapestry users Subject: Re: Best practice for new/edit object page? Thank you. Especially Jim, you have understood my "problem" perfectly! The thing is I have a hibernate OR-mapping with lots of relationships and attributes which the user should not edit or see at all in the edit page. I think I'll use your #3 - keeping the ID in the session using @Persist and reload entity from database at postback. My wonder is then - how do I detect the "new entity" scenario? If the user enters the edit page for an existing item and then clicks the link to create a new item I will have to reset the ID, am I right? My current PageLink will not do in that case. Malin On 7/10/06, Jim Steinberger <[EMAIL PROTECTED]> wrote: > > Hi Malin, > > Here are my thoughts: > > 1. Embedding the ID into the page (along with every other property of > the entity). > > Benefit: After the rewind phase sets all the OGNL-mapped properties to > your page-property-object, you can simply pass that object directly to > the service/persistence layers to be saved. > > Downside: This only works if you're comfortable embedding all of the > object's properties in the page. There's a security issue here (if it's > not an SSL connection, for example, you wouldn't want a user's password > or social security number being transferred in cleartext). There's a > practicality issue, too; if your object has a lot of associated > entities, it'd probably be too cumbersome to embed the entire > object-graph inside the page. > > > 2. Embedding the ID into the page (along with, only, properties you > intend to be updatable) > > Downside: I don't know of a great way to do this. As you asked: " but > this means I will have to redo EventServices.getEvent(eventId) after > postback. This could maybe be OK but where do I put the code?" After > all, you need the ID in order to query out the object, but that ID isn't > set via OGNL until after the rewind phase. The problem here, then, is > that you'd have to manually set all the properties to the object in your > listener. > > > 3. Keeping the ID in the session > > Implementation: Instead of setting the ID to the visit object (or > another application-state-object), declare the ID as a property of the > page, and also declare it to be persistent (e.g. the @Persist > annotation). Have your page implement the PageBeginRenderListener, and > in your pageBeginRender method, if the ID is not null, "get" the object > (I'm using Hibernate semantics) if you're not rewinding, and "load" the > object if you are. If you're rewinding, then, you'll query out the > object as it currently appears in the database, and then the rewind > phase will set all the OGNL mapped properties to it (which are the only > ones you intend to be mutable). You can then pass this to the > service/persistence layer in your listener. > > Downside: Very slight RAM overhead (I try to avoid persistent > properties/session data as much as possible, but individual Integer > objects should take awhile to add-up [I say perhaps naively]). > > Benefit: Only the properties intended to be edited will be sent to the > client. > > This also mitigates, by a degree, the synchronization issue inherent to > this. Consider the following scenario: > > Page 1 edits properties A and B. Page 2 edits properties C and D. > > Using scenario 1 above, when user Alpha loads page 1, he sees properties > A and B, and properties C and D are embedded in the page. User Beta > loads page 2, and has the reverse situation. If user Beta then submits > the form, properties C and D will be updated. When user Alpha submits > /his/ form, he'll be
RE: Best practice for new/edit object page?
You should be aware that PageLink is not session-aware (DirectLink is). If a user's session times out and they click on a PageLink, they'll see the normal Tapestry exception page when the code tries to access the session. (They won't see the "friendly" stale session page.) /dev/mrg -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Malin Ljungh Sent: Monday, July 10, 2006 2:23 PM To: Tapestry users Subject: Re: Best practice for new/edit object page? Thank you. Especially Jim, you have understood my "problem" perfectly! The thing is I have a hibernate OR-mapping with lots of relationships and attributes which the user should not edit or see at all in the edit page. I think I'll use your #3 - keeping the ID in the session using @Persist and reload entity from database at postback. My wonder is then - how do I detect the "new entity" scenario? If the user enters the edit page for an existing item and then clicks the link to create a new item I will have to reset the ID, am I right? My current PageLink will not do in that case. Malin On 7/10/06, Jim Steinberger <[EMAIL PROTECTED]> wrote: > > Hi Malin, > > Here are my thoughts: > > 1. Embedding the ID into the page (along with every other property of > the entity). > > Benefit: After the rewind phase sets all the OGNL-mapped properties to > your page-property-object, you can simply pass that object directly to > the service/persistence layers to be saved. > > Downside: This only works if you're comfortable embedding all of the > object's properties in the page. There's a security issue here (if it's > not an SSL connection, for example, you wouldn't want a user's password > or social security number being transferred in cleartext). There's a > practicality issue, too; if your object has a lot of associated > entities, it'd probably be too cumbersome to embed the entire > object-graph inside the page. > > > 2. Embedding the ID into the page (along with, only, properties you > intend to be updatable) > > Downside: I don't know of a great way to do this. As you asked: " but > this means I will have to redo EventServices.getEvent(eventId) after > postback. This could maybe be OK but where do I put the code?" After > all, you need the ID in order to query out the object, but that ID isn't > set via OGNL until after the rewind phase. The problem here, then, is > that you'd have to manually set all the properties to the object in your > listener. > > > 3. Keeping the ID in the session > > Implementation: Instead of setting the ID to the visit object (or > another application-state-object), declare the ID as a property of the > page, and also declare it to be persistent (e.g. the @Persist > annotation). Have your page implement the PageBeginRenderListener, and > in your pageBeginRender method, if the ID is not null, "get" the object > (I'm using Hibernate semantics) if you're not rewinding, and "load" the > object if you are. If you're rewinding, then, you'll query out the > object as it currently appears in the database, and then the rewind > phase will set all the OGNL mapped properties to it (which are the only > ones you intend to be mutable). You can then pass this to the > service/persistence layer in your listener. > > Downside: Very slight RAM overhead (I try to avoid persistent > properties/session data as much as possible, but individual Integer > objects should take awhile to add-up [I say perhaps naively]). > > Benefit: Only the properties intended to be edited will be sent to the > client. > > This also mitigates, by a degree, the synchronization issue inherent to > this. Consider the following scenario: > > Page 1 edits properties A and B. Page 2 edits properties C and D. > > Using scenario 1 above, when user Alpha loads page 1, he sees properties > A and B, and properties C and D are embedded in the page. User Beta > loads page 2, and has the reverse situation. If user Beta then submits > the form, properties C and D will be updated. When user Alpha submits > /his/ form, he'll be updating C and D back to what they were originally. > > This scenario still exists in scenario 3 above -- but the time-window of > this is much much smaller: properties C and D would only be reverted if > user Beta's save occurs between the Page 1's pageBeginRender method and > listener (since it loads the object in the former but doesn't save it > until the latter). > > Still, even this smaller window could well be unacceptable if your > interface allows for this scenario. I don't have a great suggestion for &g
Re: Best practice for new/edit object page?
Thank you. Especially Jim, you have understood my "problem" perfectly! The thing is I have a hibernate OR-mapping with lots of relationships and attributes which the user should not edit or see at all in the edit page. I think I'll use your #3 - keeping the ID in the session using @Persist and reload entity from database at postback. My wonder is then - how do I detect the "new entity" scenario? If the user enters the edit page for an existing item and then clicks the link to create a new item I will have to reset the ID, am I right? My current PageLink will not do in that case. Malin On 7/10/06, Jim Steinberger <[EMAIL PROTECTED]> wrote: Hi Malin, Here are my thoughts: 1. Embedding the ID into the page (along with every other property of the entity). Benefit: After the rewind phase sets all the OGNL-mapped properties to your page-property-object, you can simply pass that object directly to the service/persistence layers to be saved. Downside: This only works if you're comfortable embedding all of the object's properties in the page. There's a security issue here (if it's not an SSL connection, for example, you wouldn't want a user's password or social security number being transferred in cleartext). There's a practicality issue, too; if your object has a lot of associated entities, it'd probably be too cumbersome to embed the entire object-graph inside the page. 2. Embedding the ID into the page (along with, only, properties you intend to be updatable) Downside: I don't know of a great way to do this. As you asked: " but this means I will have to redo EventServices.getEvent(eventId) after postback. This could maybe be OK but where do I put the code?" After all, you need the ID in order to query out the object, but that ID isn't set via OGNL until after the rewind phase. The problem here, then, is that you'd have to manually set all the properties to the object in your listener. 3. Keeping the ID in the session Implementation: Instead of setting the ID to the visit object (or another application-state-object), declare the ID as a property of the page, and also declare it to be persistent (e.g. the @Persist annotation). Have your page implement the PageBeginRenderListener, and in your pageBeginRender method, if the ID is not null, "get" the object (I'm using Hibernate semantics) if you're not rewinding, and "load" the object if you are. If you're rewinding, then, you'll query out the object as it currently appears in the database, and then the rewind phase will set all the OGNL mapped properties to it (which are the only ones you intend to be mutable). You can then pass this to the service/persistence layer in your listener. Downside: Very slight RAM overhead (I try to avoid persistent properties/session data as much as possible, but individual Integer objects should take awhile to add-up [I say perhaps naively]). Benefit: Only the properties intended to be edited will be sent to the client. This also mitigates, by a degree, the synchronization issue inherent to this. Consider the following scenario: Page 1 edits properties A and B. Page 2 edits properties C and D. Using scenario 1 above, when user Alpha loads page 1, he sees properties A and B, and properties C and D are embedded in the page. User Beta loads page 2, and has the reverse situation. If user Beta then submits the form, properties C and D will be updated. When user Alpha submits /his/ form, he'll be updating C and D back to what they were originally. This scenario still exists in scenario 3 above -- but the time-window of this is much much smaller: properties C and D would only be reverted if user Beta's save occurs between the Page 1's pageBeginRender method and listener (since it loads the object in the former but doesn't save it until the latter). Still, even this smaller window could well be unacceptable if your interface allows for this scenario. I don't have a great suggestion for this, but I'm pretty sure they're there; that people have explored having transactions that span user-requests. Anyway, I'm currently migrating toward scenario 3, but I'm certainly open to other suggestions, as I was about to ask exactly this question of the list : ) Jim -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Malin Ljungh Sent: Saturday, July 08, 2006 5:21 PM To: Tapestry users Subject: Best practice for new/edit object page? Hi everyone, I'm pretty much a newbie on Tapestry and need some help. I'm building a simple web application for administering some data in a database. I use Hibernate for database connection. I'll need several pages that will handle insert of new record to table or editing an existing record. I wan't to use the same page for insert and edit. My question is basically: How should I build my pages and how should I handle state between postbacks? Let me take an example - I have a model object called Event, a page ListEvents and a page EditEvent.
Re: Best practice for new/edit object page?
On 10. Jul 2006 - 11:21:49, Gentry, Michael (Contractor) wrote: | The down side to embedding database IDs in your HTML form is they can be | changed by the user before POSTing them back to your application, which | can cause all sorts of problems. Exactly, this creates _really huge_ security issues... Anyway, I took the same approach but I've implemented a HiveMind SecurityService which is called before the object is written back to the database and which checks if the current user is allowed to execute the requested operation (read, write, delete, ...) on the object with the id. Otherwise it throws a SecurityException which is handled by the page class. This is a quite simple approach but I don't need more so it's sufficient for my needs. ACEGI integration would be more powerful and flexible - perhaps in a future version ;-) HTH Andreas - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: Best practice for new/edit object page?
The down side to embedding database IDs in your HTML form is they can be changed by the user before POSTing them back to your application, which can cause all sorts of problems. /dev/mrg -Original Message- From: Jim Steinberger [mailto:[EMAIL PROTECTED] Sent: Sunday, July 09, 2006 6:56 PM To: Tapestry users Subject: RE: Best practice for new/edit object page? Hi Malin, Here are my thoughts: 1. Embedding the ID into the page (along with every other property of the entity). Benefit: After the rewind phase sets all the OGNL-mapped properties to your page-property-object, you can simply pass that object directly to the service/persistence layers to be saved. Downside: This only works if you're comfortable embedding all of the object's properties in the page. There's a security issue here (if it's not an SSL connection, for example, you wouldn't want a user's password or social security number being transferred in cleartext). There's a practicality issue, too; if your object has a lot of associated entities, it'd probably be too cumbersome to embed the entire object-graph inside the page. 2. Embedding the ID into the page (along with, only, properties you intend to be updatable) Downside: I don't know of a great way to do this. As you asked: " but this means I will have to redo EventServices.getEvent(eventId) after postback. This could maybe be OK but where do I put the code?" After all, you need the ID in order to query out the object, but that ID isn't set via OGNL until after the rewind phase. The problem here, then, is that you'd have to manually set all the properties to the object in your listener. 3. Keeping the ID in the session Implementation: Instead of setting the ID to the visit object (or another application-state-object), declare the ID as a property of the page, and also declare it to be persistent (e.g. the @Persist annotation). Have your page implement the PageBeginRenderListener, and in your pageBeginRender method, if the ID is not null, "get" the object (I'm using Hibernate semantics) if you're not rewinding, and "load" the object if you are. If you're rewinding, then, you'll query out the object as it currently appears in the database, and then the rewind phase will set all the OGNL mapped properties to it (which are the only ones you intend to be mutable). You can then pass this to the service/persistence layer in your listener. Downside: Very slight RAM overhead (I try to avoid persistent properties/session data as much as possible, but individual Integer objects should take awhile to add-up [I say perhaps naively]). Benefit: Only the properties intended to be edited will be sent to the client. This also mitigates, by a degree, the synchronization issue inherent to this. Consider the following scenario: Page 1 edits properties A and B. Page 2 edits properties C and D. Using scenario 1 above, when user Alpha loads page 1, he sees properties A and B, and properties C and D are embedded in the page. User Beta loads page 2, and has the reverse situation. If user Beta then submits the form, properties C and D will be updated. When user Alpha submits /his/ form, he'll be updating C and D back to what they were originally. This scenario still exists in scenario 3 above -- but the time-window of this is much much smaller: properties C and D would only be reverted if user Beta's save occurs between the Page 1's pageBeginRender method and listener (since it loads the object in the former but doesn't save it until the latter). Still, even this smaller window could well be unacceptable if your interface allows for this scenario. I don't have a great suggestion for this, but I'm pretty sure they're there; that people have explored having transactions that span user-requests. Anyway, I'm currently migrating toward scenario 3, but I'm certainly open to other suggestions, as I was about to ask exactly this question of the list : ) Jim -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Malin Ljungh Sent: Saturday, July 08, 2006 5:21 PM To: Tapestry users Subject: Best practice for new/edit object page? Hi everyone, I'm pretty much a newbie on Tapestry and need some help. I'm building a simple web application for administering some data in a database. I use Hibernate for database connection. I'll need several pages that will handle insert of new record to table or editing an existing record. I wan't to use the same page for insert and edit. My question is basically: How should I build my pages and how should I handle state between postbacks? Let me take an example - I have a model object called Event, a page ListEvents and a page EditEvent. This is the essentials of my EditEvent.java: public abstract Event getEvent(); public abstract
RE: Best practice for new/edit object page?
Hi Malin, Here are my thoughts: 1. Embedding the ID into the page (along with every other property of the entity). Benefit: After the rewind phase sets all the OGNL-mapped properties to your page-property-object, you can simply pass that object directly to the service/persistence layers to be saved. Downside: This only works if you're comfortable embedding all of the object's properties in the page. There's a security issue here (if it's not an SSL connection, for example, you wouldn't want a user's password or social security number being transferred in cleartext). There's a practicality issue, too; if your object has a lot of associated entities, it'd probably be too cumbersome to embed the entire object-graph inside the page. 2. Embedding the ID into the page (along with, only, properties you intend to be updatable) Downside: I don't know of a great way to do this. As you asked: " but this means I will have to redo EventServices.getEvent(eventId) after postback. This could maybe be OK but where do I put the code?" After all, you need the ID in order to query out the object, but that ID isn't set via OGNL until after the rewind phase. The problem here, then, is that you'd have to manually set all the properties to the object in your listener. 3. Keeping the ID in the session Implementation: Instead of setting the ID to the visit object (or another application-state-object), declare the ID as a property of the page, and also declare it to be persistent (e.g. the @Persist annotation). Have your page implement the PageBeginRenderListener, and in your pageBeginRender method, if the ID is not null, "get" the object (I'm using Hibernate semantics) if you're not rewinding, and "load" the object if you are. If you're rewinding, then, you'll query out the object as it currently appears in the database, and then the rewind phase will set all the OGNL mapped properties to it (which are the only ones you intend to be mutable). You can then pass this to the service/persistence layer in your listener. Downside: Very slight RAM overhead (I try to avoid persistent properties/session data as much as possible, but individual Integer objects should take awhile to add-up [I say perhaps naively]). Benefit: Only the properties intended to be edited will be sent to the client. This also mitigates, by a degree, the synchronization issue inherent to this. Consider the following scenario: Page 1 edits properties A and B. Page 2 edits properties C and D. Using scenario 1 above, when user Alpha loads page 1, he sees properties A and B, and properties C and D are embedded in the page. User Beta loads page 2, and has the reverse situation. If user Beta then submits the form, properties C and D will be updated. When user Alpha submits /his/ form, he'll be updating C and D back to what they were originally. This scenario still exists in scenario 3 above -- but the time-window of this is much much smaller: properties C and D would only be reverted if user Beta's save occurs between the Page 1's pageBeginRender method and listener (since it loads the object in the former but doesn't save it until the latter). Still, even this smaller window could well be unacceptable if your interface allows for this scenario. I don't have a great suggestion for this, but I'm pretty sure they're there; that people have explored having transactions that span user-requests. Anyway, I'm currently migrating toward scenario 3, but I'm certainly open to other suggestions, as I was about to ask exactly this question of the list : ) Jim -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Malin Ljungh Sent: Saturday, July 08, 2006 5:21 PM To: Tapestry users Subject: Best practice for new/edit object page? Hi everyone, I'm pretty much a newbie on Tapestry and need some help. I'm building a simple web application for administering some data in a database. I use Hibernate for database connection. I'll need several pages that will handle insert of new record to table or editing an existing record. I wan't to use the same page for insert and edit. My question is basically: How should I build my pages and how should I handle state between postbacks? Let me take an example - I have a model object called Event, a page ListEvents and a page EditEvent. This is the essentials of my EditEvent.java: public abstract Event getEvent(); public abstract void setEvent(Event event); public void pageBeginRender(PageEvent event) { if(getEvent() == null) // new Event setEvent(new Event()); } Could/should the thing in pageBeginRender be done by injection instead? And this is the link between the Event list and the EditEvent page in ListEvents.java: @InjectPage("EditEvent") public abstract EditEvent getEditEvent(); public IPage editEvent(int eventId) { EditEvent editEvent = getEditEvent(); editEvent.setEvent(EventServices.g