Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: JPA and JSR 303 problems in stateful web apps
PostPosted: Sat Mar 27, 2010 7:37 pm 
Newbie

Joined: Fri Mar 26, 2010 3:39 pm
Posts: 6
Hi, guys !

In my opinion, JPA is a specification for stateless web app, and, of course, I will give two examples of that.
First at all, JPA doesn't provide flushmode in MANUAL.To second reason, I will have to write a little more.....
I think JSR 303 spec doesn't fix some validations issues in truly stateful apps.
Imagine we have this domain model:

Code:
@Entity
public class Person {
   @javax.persistence.OneToMany(fetch = javax.persistence.FetchType.LAZY, cascade = CascadeType.ALL)
   @Valid
   java.util.List<Address> addresses = new java.util.ArrayList<Address>();

   @javax.persistence.OneToMany(fetch = javax.persistence.FetchType.LAZY, cascade = CascadeType.ALL)
   @Valid
   java.util.List<PhoneNumber> phoneNumbers = new java.util.ArrayList<PhoneNumber>();

   @org.hibernate.validator.NotEmpty
   @Column(name = "name")
   String name;
   ....
}

@Entity
public class Address {
   @org.hibernate.validator.NotEmpty
   @Column(name = "street")
   String street;
   .....
}

@Entity
public class PhoneNumber {
   @org.hibernate.validator.NotEmpty
   @Column(name = "phone")
   String phone;
   .....
}


Very simple, isn't it ? Well, we will continue with our mental experiment. Imagine I want to make a wizard with four steps:

First step: I will fill Person information
Second Step. I will fill one or many addresses of this person
Third Step. I will fill one or many phone numbers of this person
Fourth Step. I will show all the information and ask for confirmation.

Step 1, 2 and 3 will do exactly the same on Next button:
Code:
   
   public class persistPersonInfo() {
      entityManager.persist(personInstance);
   }


Next button on Step 4:
Code:
   
   public class flushPersonInfo() {
      entityManager.flush(personInstance);
   }


As you can see, before finishing my wizard, I persist Person entity instance and all its addresses and phone numbers in persistence context, NOT in database, because I configured my flushmode in MANUAL. Only when user confirms at the end of the wizard, I flush all information in database in one shot, as it should be.

Problem is validation.

Imagine in first step my user doesn't fill Persons name. Validation will fail, and will ask to user to fill Persons name... my user will fill Persons name and when he clicks Next, app will crash, because Person instance will be detached.

How I fixed it ? Very simple:

Code:
   public class persistPersonInfo() {
      ClassValidator personValidator=new ClassValidator(Person.class);
      InvalidValues values=personValidator.getInvalidValues(personInstance);
      if(invalidValues==0) {
         entityManager.persist(personInstance);
      }
   }


It seems to be fixed, but it isn't. Problem is the second and third steps of wizard. Imagine that our user doesn't insert street information in second step, and press Next.I'm saving my addresses and phone numbers using cascade, but Hibernate sometimes proxies addresses and phone numbers instances, so, when I persist Person and all related collections, validation doesn't work ( because validation annotations doesn't pass from original class to proxied class )

Ok, but JPA specification says we can use EntityListeners. I change all my domain model classes adding @EntityListeners(JPAValidateListener.class), and it seems to fixed everything.

NO !! Why ?

Imagine I develop a second wizard, to edit Person information, with same four steps, but showing Person information, and allowing user to edit it.

When I execute method persistPersonInfo() validation doesn't run, because JPA specification says validation will run in flush() method ( PrePersist and PreUpdate events ) ! But I want validation in persist(), in my first, second and third steps of my wizard, not at the end of it !

If I'm using frameworks like Spring, I have no problems, because usually I persist AND flush in every step of my wizard ( not saving my state in persistence context, because it dissapears, but in another place ). But I'm using Seam, and I want to flush at the end of my wizard.

Another option is to use Interceptors, but I don't want to manage my transactions using Hibernate Transactions, I want to use Entity Manager Transaction ( according to JPA spec )

One last thing ... Emmanuel B, if you want to answer me, give me solutions, don't react as usually, saying I didn't understand something. And if I didn't understand, explain me WHAT I didn't understand, in order to help me. Thanks !

P.S. I'm sorry for my english !


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Wed Mar 31, 2010 10:46 am 
Newbie

Joined: Tue Nov 11, 2003 6:31 pm
Posts: 8
You should have a look at validation groups, it seems this is what you are looking for to implement partial validations in wizards.


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Wed Mar 31, 2010 1:28 pm 
Newbie

Joined: Fri Mar 26, 2010 3:39 pm
Posts: 6
Hi, William ( I guess it is you !! ).

First at all, my congrats of GraniteDS. We are using it and we think is awesome !!

Are you specifically talking about Life Cycle Phase of Bean Validations ?

Thanks !


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Wed Mar 31, 2010 1:47 pm 
Newbie

Joined: Fri Mar 26, 2010 3:39 pm
Posts: 6
William:

My problem is not to validate a subset of properties or beans, my problem is JPA specification inconsistencies.

Best regards


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Thu Apr 01, 2010 5:06 am 
Newbie

Joined: Tue Nov 11, 2003 6:31 pm
Posts: 8
With manual flush, I would just call persist() once before the first step with an empty object, then at each step call partial validation with groups for each part of the form, and finally call flush() on the last step.
With an conversation/extended persistence context the object stays managed between requests so you don't have to persist() each time.


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Thu Apr 01, 2010 9:00 am 
Newbie

Joined: Fri Mar 26, 2010 3:39 pm
Posts: 6
You are totally right, William. But my problem is not to use persist or not in each step. My problem is that validations doesn't work calling validation, because all collections of Person instance may be proxied, and validations doesn't work with proxied objects in cascade. The problem is:

Validation in CASCADE doesn't work if any of my related collection is proxied . If collection is proxied, Hibernate doesn't read validations annotations and not work, because annotations aren't inherited to proxies. English it isn't my language, so is very difficult to express myself clearly.

Best regards!


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Thu Apr 01, 2010 10:33 am 
Newbie

Joined: Tue Nov 11, 2003 6:31 pm
Posts: 8
I don't understand how you can get proxied collections or objects in this context, at least proxied by Hibernate.
Are they proxied by Seam ?


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Thu Apr 01, 2010 11:11 am 
Newbie

Joined: Fri Mar 26, 2010 3:39 pm
Posts: 6
Imagine you are editing a Person. When you ask Hibernate to get all its Addresses and Phone Numbers ( both related collections to Person ) with lazy loading, sometimes Hibernate gives you Addresses instances, and sometimes Addresses proxied instances. Validation fails when Hibernate gives to you proxies, because cannot validate them, because annotations are not in proxied instances.

Example

personInstance is an instance of Person

Scenario 1:

It has three addresses ( eager loading )

address1 -> Class Address.class
address2 -> Class Address.class
address3 -> Class Address.class

Everything works fine here.

Scenario 1:

It has three addresses ( lazy loading )

address1 -> Class Address_javaassist12123.class
address2 -> Class Address_javaassist12123.class
address3 -> Class Address_javaassist12123.class

Validation fails, because Address_javaassist12123.class didn't receive annotations from class Address.class

I hope this example is clear


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Thu Apr 01, 2010 12:13 pm 
Newbie

Joined: Tue Nov 11, 2003 6:31 pm
Posts: 8
If I understand correctly, you have this problem in the case of editing (in the case of creation of a new Person there is no chance that you get proxies).

I think the spec is perfectly right in saying that validation should not be cascaded to lazy associations, otherwise you would trigger the complete loading of the object graph
at every validation and this is not suitable.

You should probably force the loading of these associations at the beginning of your wizard with left join fetch or something like this. You will probably need the addresses anyway if you display them somewhere.


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Fri Apr 02, 2010 10:59 am 
Newbie

Joined: Fri Mar 26, 2010 3:39 pm
Posts: 6
You are right !! That was the reason !! Validation cannot work in cascade because ORM doesn't know where to stop !!

Thanks, William !!!

P.S. But.... of course.... Hibernate could check all dirty instances to validate them... but definitively you're right anyway. Thank you again !!


Top
 Profile  
 
 Post subject: Re: JPA and JSR 303 problems in stateful web apps
PostPosted: Thu Feb 17, 2011 3:54 am 
Newbie

Joined: Thu Feb 17, 2011 3:23 am
Posts: 2
I am using it and it is working well until now. I just got some idea about the first post I’ve read. Anyway, simpler would be great for this stateful web apps.

_________________
indianapolis seo


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.