-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Non-intrusive constraint declaration
PostPosted: Fri Apr 04, 2008 11:45 am 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
First, I have to say that I like very much this specification. I'm project lead for OpenXava(http://www.openxava.org/) framework, and no matter your listen me or no, OpenXava will implement JSR-303.

The way you thinked for defining constraint annotations, is very good. But, it would be cool to add the possibility to define a constraint annotation without 'message', 'groups' and @ValidatorClass. A non-intrusive way as an option.

For example, it will be ideal define a constraint using XML in this way:

Code:
<constraint>
  <annotation class="javax.persistence.Column"/>
  <validator class="javax.validation.validators.JPAColumnLengthConstraint"
  <message id="beancheck.length"/>
  <groups />
</constraint>

<constraint>
  <annotation class="javax.persistence.Column"/>
  <validator class="javax.validation.validators.JPAColumnNotNullConstraint"
  <message id="beancheck.notNull"/>
  <groups />
</constraint>



Why this non-instrusive approach is practical ? Because you can use already existing annotations as validation annotations. This has the next advantages:
    - You can add validation to your existing application without rewrite it (very important).
    - You can use annotation which source code outside of your control as validation annotations.
    - You can avoid redundancy.

Moreover, you have a way for avoid JPA / Bean Validation rendundacy (http://forum.hibernate.org/viewtopic.php?t=985342) with little effort. Even you can avoid redundacy using the current JPA 1.0 specification, without wait to JPA 2.0.

What do you think ?

Cheers
Javier Paniza


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 07, 2008 4:39 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
We want to permit @ConstraintValidator to be defined through XML, you proposal goes a step further. This is interesting.

The main problem I see is that the message is likely to be overridden. This will force people to use XML at declaration time which defeats the whole purpose of annotation reusability.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 08, 2008 3:56 am 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
emmanuel wrote:
We want to permit @ConstraintValidator to be defined through XML, you proposal goes a step further. This is interesting.

Fantastic!

emmanuel wrote:
This will force people to use XML at declaration time ...

You're right. Using XML only for overriding a message is very ugly.
Anyways, we only will use XML for annotations when we have no access to the source code of the annotation. And even in this case we can explore some alternatives to your problem, for example:

1. Using a message annoations; in this way:

Code:
@Column(length=40) @Message(forAnnotation=Column.class, "product_description_message_id")
private String description;

forAnnotation can be optional

2. Using a convention for i18n files:

In Java:
Code:
@Entity
public class Product {
 
  @Column(length=20)
  private String name;
}

And in the i18n file:
Code:
bean.validation.Product.name[Column]=Name of the product cannot be so long


I like more the option 2. It's just the way of OpenXava for i18n. In fact, OpenXava 3 does not have any i18n info in its annotations.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 10, 2008 6:20 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
1 does not work as you can have multiple times the same annotation @Columns(...)

2 why not. but you need the fqcn which makes the property file quite verbose.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 10, 2008 6:22 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
actually 2 suffers the same problem as 1

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 11, 2008 3:40 am 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
emmanuel wrote:
actually 2 suffers the same problem as 1


But, you write this:
Code:
bean.validation.Product.name[Column.length]=Name of the product cannot be so long

To avoid ambiguity. Only special case (as annotation with @Pattern style) may be problematic. And remember that this would not be the 'normal' way for declaring constraint, but a way for reuse existing annotations with a JSR-303.

The amount of cases of ambiguity will be very, very low. And this feature it's very useful, imagine integration of JSR-303 with a JPA 1.0 implementation, or any other existing framework or library.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 11, 2008 1:19 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
This is not uncommon
Code:
@JoinColumns
@JoinTable(...{@JoinColumn, @JoinColumn} )

etc etc

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 11, 2008 1:39 pm 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
emmanuel wrote:
This is not uncommon
Code:
@JoinColumns
@JoinTable(...{@JoinColumn, @JoinColumn} )

etc etc


Then, other option for i18n file:
Code:
bean.validation.Product.name[@Column(length=20)]=Name of the product cannot be so long


But, this only will be used when the developer needs override the standard message of that annotation in some property, and the annotation is repeated in that property. This is not the usual case. Indeed, in business applications is usual to have a generic group of coherent messages for the entire application, not one per property.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 18, 2008 8:43 am 
Beginner
Beginner

Joined: Thu Apr 17, 2008 5:47 pm
Posts: 26
I also need this Non-intrusive constraint declaration - I have a domain model annotated with JPA annotations and I'm not permitted to add constraint annotations on it or change it in any other way.

I think the xml is ok, but first there should be a way to do it programatically. The problem is with this message per constraint annotation instance. I think we can live only with the default one also. The same goes for the groups - so I will just skip them.

Further the constraint annotation is linked statically (compile-time) to the constraint validator via @ConstraintValidator annotation on it.
This is nice for the default approach.

But in a more dynamic world one can workaround this in runtime via bytecode modification - inject @ConstraintValidator in a @Column (JPA) annotation (not sure if it is possible :)?

What about inventing a ConstraintRepository and ConstraintDescriptor :
Code:
public interface ConstraintRepository {

   ConstraintDescriptor getConstraintDescriptor(Annotation constraintAnnotation);
}

public interface ConstraintDescriptor {

   Constraint getConstraint();

   String getDefaultMessage();

   String[] getDefaultGroups();
}



I haven't played with the model above, but I think it will be a nice option. As I see the way the ClassValidator in hibernate obtains the validator (Constraint in the JSR) :
Code:
   private Validator createValidator(Annotation annotation) {
      try {
         ValidatorClass validatorClass = annotation.annotationType().getAnnotation( ValidatorClass.class );
         if ( validatorClass == null ) {
            return null;
      }
// ...


This can be configured to be optional or enforced depending on the intent, but something like this:
Code:
if ( validatorClass == null ) {
   ConstraintDescriptor  cd = contraintRepository.getConstraintDescriptor(annotation);
   if (cd != null) {
      validatorClass =  cd.getConstraint();
   } else {
           return null;
        }
}


Ok, I have mixed the JSR API and the Hibernate APIs, but I hope you get the idea.

Even if you don't like to complicate the API it will be at least nice if there is a way to extend it like this, so that the base is reusable somehow..


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 18, 2008 1:19 pm 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
Hi Bodrin,

I like your idea of a pluggable ConstraintRepository.
This give us, the framework developer, a lot of flexibility.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 23, 2008 8:46 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
So you want some sort of constraintTransformer that takes a random annotation and create a JSR 303 annotation out of it right?
Where would the constraintTransformer get his rules of? How would it look like?

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 25, 2008 12:50 pm 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
emmanuel wrote:
So you want some sort of constraintTransformer that takes a random annotation and create a JSR 303 annotation out of it right?

Not exactly.
I want to declare a JSR-303 constraint and link it to an already existing random annotation, without touching it. Just as explained in the fist example of this thread.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 02, 2008 7:30 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
javierpaniza wrote:
emmanuel wrote:
So you want some sort of constraintTransformer that takes a random annotation and create a JSR 303 annotation out of it right?

Not exactly.
I want to declare a JSR-303 constraint and link it to an already existing random annotation, without touching it. Just as explained in the fist example of this thread.


same questions :) ?

Where would the "random annotations be magically converted" get its rules of? How would it look like?

BTW the constraintTransformer should address your demand, I think when we answer those questions.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 05, 2008 1:21 pm 
Beginner
Beginner

Joined: Fri Jan 14, 2005 7:47 am
Posts: 37
Location: Spain
emmanuel wrote:
Where would the "random annotations be magically converted" get its rules of? How would it look like?

The annotation does not need to be converted. Because it's a non-instrusive constraint declaration. That, I can add a constraint validator to the already existing @Column JPA annotation in this way:
Code:
<constraint>
  <annotation class="javax.persistence.Column"/>
  <validator class="com.mycompany.myapplication.myvalidations.MyConstraintForJPAColumn"
  <message id="beancheck.length"/>
  <groups />
</constraint>

Then the JSR-303 validation engine detects that @Column has a constraint associated to it, so enforce it.
You do not need convert @Column in other thing.
emmanuel wrote:
BTW the constraintTransformer should address your demand, I think when we answer those questions.

Yes, of course. constraintTransformer is more flexible, but also more complicate. XML is easier.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 05, 2008 6:13 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
javierpaniza wrote:
Code:
<constraint>
  <annotation class="javax.persistence.Column"/>
  <validator class="com.mycompany.myapplication.myvalidations.MyConstraintForJPAColumn"
  <message id="beancheck.length"/>
  <groups />
</constraint>

But here is the thing, you probably don't want the same groups / messages for all your columns in your application, so somehow it is specific to a given annotations on a given property.

_________________
Emmanuel


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next

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.