You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by taltun <tu...@gmail.com> on 2009/07/20 11:42:20 UTC

Prevent persisting data when validation fails

When submitting a form using manual validation in my action. Even when the
validation fails and the action method supposed to be called is not called
at all, the dirty data is persisted ?

How can I prevent data from being persisted if the validation fails ?

Note:  I use prepare method to load e.g an user object from a
manager/service. And the data relates to the user object that is about. 

-taltun
-- 
View this message in context: http://www.nabble.com/Prevent-persisting-data-when-validation-fails-tp24566713p24566713.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Prevent persisting data when validation fails

Posted by Jim Kiley <jh...@summa-tech.com>.
What are you using to manage persistence?  Can we see your action's source
code?

On Mon, Jul 20, 2009 at 5:42 AM, taltun <tu...@gmail.com> wrote:

>
> When submitting a form using manual validation in my action. Even when the
> validation fails and the action method supposed to be called is not called
> at all, the dirty data is persisted ?
>
> How can I prevent data from being persisted if the validation fails ?
>
> Note:  I use prepare method to load e.g an user object from a
> manager/service. And the data relates to the user object that is about.
>
> -taltun
> --
> View this message in context:
> http://www.nabble.com/Prevent-persisting-data-when-validation-fails-tp24566713p24566713.html
> Sent from the Struts - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>


-- 
Jim Kiley
Senior Technical Consultant | Summa
[p] 412.258.3346
http://www.summa-tech.com

Re: Prevent persisting data when validation fails

Posted by taltun <tu...@gmail.com>.
Ok.

- What is the best way to copy a persistent object ? Using BeanUtil.copy or
clone, etc?





Greg Lindholm-2 wrote:
> 
>> I use JPA (hibernate) to persist.
>>
>>
>>
>> An example of action that use prepare to load a person object from
>> transactional manager. When the validate fails and it return back to the
>> input page the request ends and the transaction persists the dirty user
>> object to database. The dirty user object should not be persisted if the
>> validation fails.:
>>
>> public class PersonAction extends BaseAction implements Preparable {
>>
>> private PersonManager personManager;
>> private Person person;
>>
>> public void prepare() {
>>        person = personManager.getPerson(id);
>> }
>>
>> public String savePerson() {
>>       manager.savePerson(person);
>>       return SUCCESS;
>> }
>>
>> public void validate() {
>>       if (person.firstName.length < 5 and person.firstName > 10) {
>>           addActionError("Firstname length should be between 5 and 10
>> characters.");
>>        }
>> }
>>
>> }
>>
>>
> This isn't really a Struts problem, it just the way Hibernate works.
> 
> If you make changes to a monitored object (Persistent state) from the
> database then Hibernate will detect this and save the changes to the
> database when you commit the transaction.  There is actually no need to
> call
> "save" to update a db object it will happen automatically.
> 
> To "fix" your problem you have a couple of choices:
> 
> 1) Don't make changes to db objects unless you are sure you want them
> saved.  This would mean changing your actions to work with copies of the
> objects or Detached objects instead of the actually db objects (this is
> what
> I do).
> 
> 2) Don't commit the transaction if the validation fails.  Do a rollback
> instead.
> 
> 

-- 
View this message in context: http://www.nabble.com/Prevent-persisting-data-when-validation-fails-tp24566713p24571177.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Prevent persisting data when validation fails

Posted by Burton Rhodes <bu...@gmail.com>.
I had the same problem while using the opensessioninview pattern.
Since this pattern in struts uses an interceptor, in the OSiV
interceptor I checked to see if validation had failed in an Action.
If so, I "rolled back" the transaction to make sure it didn't persist
the data.  I eventually removed this "roll back" logic because I
thought it was more of a hack than a solution.  I also ran into some
issues with the evict() method so didn't go that route.  Eventually I
moved to manual commit using JPA with Hibernate and managed the
process myself.  Hibernate's default setting is auto commit = true.  I
think you'll find controlling the process yourself is not that
difficult and makes for cleaner code.


On Mon, Jul 20, 2009 at 2:07 PM, Greg Lindholm<gr...@gmail.com> wrote:
>> Thank you very much!!
>>
>> During my research, I remember some one solved the issue by creating an
>> Struts 2 intercepter. He placed the intercepter right after the
>> validationIntercepter. The job of the intercepter was to check if
>> getActionErrors or getFieldErrors collections was not empty than it closed
>> and flushed the entityManager. But he didn't specified what intercepter
>> method (before, inside or after the action was invoked) he implemented.
>>
>> Do you think this is a solution ?
>> Any disadvangages ?
>> What intercepter method do you think will be the correct one to implement?
>>
>>
>>
> You could probably make this work. You can take a look at the Workflow
> Interceptor as an example of how to tell if there are errors.
>
> You would have to do your stuff before calling invocation.invoke(); cause
> after is too late, the result will have already been rendered.
>
> Disadvantages are hard to determine, depends a lot on how you are managing
> your Hibernate sessions. If you clear() /close()/rollback you are throwing
> away all changes in the Hibernate session not just the one object you that
> failed validation.   To avoid these issues that is why I always work with a
> copy of the db object.
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Prevent persisting data when validation fails

Posted by Greg Lindholm <gr...@gmail.com>.
> Thank you very much!!
>
> During my research, I remember some one solved the issue by creating an
> Struts 2 intercepter. He placed the intercepter right after the
> validationIntercepter. The job of the intercepter was to check if
> getActionErrors or getFieldErrors collections was not empty than it closed
> and flushed the entityManager. But he didn't specified what intercepter
> method (before, inside or after the action was invoked) he implemented.
>
> Do you think this is a solution ?
> Any disadvangages ?
> What intercepter method do you think will be the correct one to implement?
>
>
>
You could probably make this work. You can take a look at the Workflow
Interceptor as an example of how to tell if there are errors.

You would have to do your stuff before calling invocation.invoke(); cause
after is too late, the result will have already been rendered.

Disadvantages are hard to determine, depends a lot on how you are managing
your Hibernate sessions. If you clear() /close()/rollback you are throwing
away all changes in the Hibernate session not just the one object you that
failed validation.   To avoid these issues that is why I always work with a
copy of the db object.

Re: Prevent persisting data when validation fails

Posted by taltun <tu...@gmail.com>.
Thank you very much!!

During my research, I remember some one solved the issue by creating an
Struts 2 intercepter. He placed the intercepter right after the
validationIntercepter. The job of the intercepter was to check if
getActionErrors or getFieldErrors collections was not empty than it closed
and flushed the entityManager. But he didn't specified what intercepter
method (before, inside or after the action was invoked) he implemented.

Do you think this is a solution ? 
Any disadvangages ?
What intercepter method do you think will be the correct one to implement?






Greg Lindholm-2 wrote:
> 
>>
>> By the way, how can I let JPA return a deatached object ?
>>
>> I make use of GenericDaoJpa.java which is attached to this message.
>> http://www.nabble.com/file/p24571326/GenericDaoJpa.java
>> GenericDaoJpa.java
>>
>>
>>
> See
> http://stackoverflow.com/questions/31446/detach-an-entity-from-jpa-ejb3-persistence-contextfor
> discussion but the answer seems to be use the Hibernate
> session.evict(object) method.
> 
> It may be easier to do an EntityManager.clear() or close() when validation
> fails.  Of course this will only work if you only use manual validation
> with
> the validate() method, if you use declarative validation then you never
> get
> a chance to react when validation fails.
> 
>   ( @Struts Experts: Is there any way to call an action method
> post-validation but before the result is taken so you can do some stuff
> when
> validation fails?  I know about PreResultListener but don't think it's
> what
> I want.)
> 
> 
>> What is the best way to copy a persistent object ? Using BeanUtil.copy or
> clone, etc?
> 
> I guess you can use clone, but I always write a copy constructor for
> entity
> classes so I have more control over handling of references to other
> entities.
> 
> 

-- 
View this message in context: http://www.nabble.com/Prevent-persisting-data-when-validation-fails-tp24566713p24574368.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Prevent persisting data when validation fails

Posted by Greg Lindholm <gr...@gmail.com>.
>
> By the way, how can I let JPA return a deatached object ?
>
> I make use of GenericDaoJpa.java which is attached to this message.
> http://www.nabble.com/file/p24571326/GenericDaoJpa.java GenericDaoJpa.java
>
>
>
See
http://stackoverflow.com/questions/31446/detach-an-entity-from-jpa-ejb3-persistence-contextfor
discussion but the answer seems to be use the Hibernate
session.evict(object) method.

It may be easier to do an EntityManager.clear() or close() when validation
fails.  Of course this will only work if you only use manual validation with
the validate() method, if you use declarative validation then you never get
a chance to react when validation fails.

  ( @Struts Experts: Is there any way to call an action method
post-validation but before the result is taken so you can do some stuff when
validation fails?  I know about PreResultListener but don't think it's what
I want.)


> What is the best way to copy a persistent object ? Using BeanUtil.copy or
clone, etc?

I guess you can use clone, but I always write a copy constructor for entity
classes so I have more control over handling of references to other
entities.

Re: Prevent persisting data when validation fails

Posted by taltun <tu...@gmail.com>.
By the way, how can I let JPA return a deatached object ?

I make use of GenericDaoJpa.java which is attached to this message.
http://www.nabble.com/file/p24571326/GenericDaoJpa.java GenericDaoJpa.java 


Greg Lindholm-2 wrote:
> 
>> I use JPA (hibernate) to persist.
>>
>>
>>
>> An example of action that use prepare to load a person object from
>> transactional manager. When the validate fails and it return back to the
>> input page the request ends and the transaction persists the dirty user
>> object to database. The dirty user object should not be persisted if the
>> validation fails.:
>>
>> public class PersonAction extends BaseAction implements Preparable {
>>
>> private PersonManager personManager;
>> private Person person;
>>
>> public void prepare() {
>>        person = personManager.getPerson(id);
>> }
>>
>> public String savePerson() {
>>       manager.savePerson(person);
>>       return SUCCESS;
>> }
>>
>> public void validate() {
>>       if (person.firstName.length < 5 and person.firstName > 10) {
>>           addActionError("Firstname length should be between 5 and 10
>> characters.");
>>        }
>> }
>>
>> }
>>
>>
> This isn't really a Struts problem, it just the way Hibernate works.
> 
> If you make changes to a monitored object (Persistent state) from the
> database then Hibernate will detect this and save the changes to the
> database when you commit the transaction.  There is actually no need to
> call
> "save" to update a db object it will happen automatically.
> 
> To "fix" your problem you have a couple of choices:
> 
> 1) Don't make changes to db objects unless you are sure you want them
> saved.  This would mean changing your actions to work with copies of the
> objects or Detached objects instead of the actually db objects (this is
> what
> I do).
> 
> 2) Don't commit the transaction if the validation fails.  Do a rollback
> instead.
> 
> 

-- 
View this message in context: http://www.nabble.com/Prevent-persisting-data-when-validation-fails-tp24566713p24571326.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Prevent persisting data when validation fails

Posted by Greg Lindholm <gr...@gmail.com>.
> I use JPA (hibernate) to persist.
>
>
>
> An example of action that use prepare to load a person object from
> transactional manager. When the validate fails and it return back to the
> input page the request ends and the transaction persists the dirty user
> object to database. The dirty user object should not be persisted if the
> validation fails.:
>
> public class PersonAction extends BaseAction implements Preparable {
>
> private PersonManager personManager;
> private Person person;
>
> public void prepare() {
>        person = personManager.getPerson(id);
> }
>
> public String savePerson() {
>       manager.savePerson(person);
>       return SUCCESS;
> }
>
> public void validate() {
>       if (person.firstName.length < 5 and person.firstName > 10) {
>           addActionError("Firstname length should be between 5 and 10
> characters.");
>        }
> }
>
> }
>
>
This isn't really a Struts problem, it just the way Hibernate works.

If you make changes to a monitored object (Persistent state) from the
database then Hibernate will detect this and save the changes to the
database when you commit the transaction.  There is actually no need to call
"save" to update a db object it will happen automatically.

To "fix" your problem you have a couple of choices:

1) Don't make changes to db objects unless you are sure you want them
saved.  This would mean changing your actions to work with copies of the
objects or Detached objects instead of the actually db objects (this is what
I do).

2) Don't commit the transaction if the validation fails.  Do a rollback
instead.

Re: Prevent persisting data when validation fails

Posted by taltun <tu...@gmail.com>.
I use JPA (hibernate) to persist.



An example of action that use prepare to load a person object from
transactional manager. When the validate fails and it return back to the
input page the request ends and the transaction persists the dirty user
object to database. The dirty user object should not be persisted if the
validation fails.:

public class PersonAction extends BaseAction implements Preparable {

private PersonManager personManager;
private Person person;

public void prepare() {
        person = personManager.getPerson(id);           
}

public String savePerson() {
       manager.savePerson(person);
       return SUCCESS;
}

public void validate() {
       if (person.firstName.length < 5 and person.firstName > 10) {
           addActionError("Firstname length should be between 5 and 10
characters.");
       }
}

}


taltun wrote:
> 
> When submitting a form using manual validation in my action. Even when the
> validation fails and the action method supposed to be called is not called
> at all, the dirty data is persisted ?
> 
> How can I prevent data from being persisted if the validation fails ?
> 
> Note:  I use prepare method to load e.g an user object from a
> manager/service. And the data relates to the user object that is about. 
> 
> -taltun
> 

-- 
View this message in context: http://www.nabble.com/Prevent-persisting-data-when-validation-fails-tp24566713p24569948.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org