unique annotation

324 views
Skip to first unread message

Fırat KÜÇÜK

unread,
Nov 24, 2009, 9:24:33 AM11/24/09
to play-framework
Hi,
I looked for any way to check annotation based restriction for unique values?
Is @Unique or some annotation like that convenient for validation?

--
FIRAT KÜÇÜK

Guillaume Bort

unread,
Nov 24, 2009, 9:33:35 AM11/24/09
to play-fr...@googlegroups.com
Do you mean a unique value in the database ? I think that you should
look at a JPA annotation.

2009/11/24 Fırat KÜÇÜK <firat...@gmail.com>:
> --
>
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To post to this group, send email to play-fr...@googlegroups.com.
> To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.
>
>
>

Fırat KÜÇÜK

unread,
Nov 24, 2009, 9:56:05 AM11/24/09
to play-fr...@googlegroups.com
In fact a JPA based @uniqueConstraint annotation give us the ability
to define the constraints.
It is not much more than a definition. And when we try to save a
duplicate entry. We will get the same exception
before writing @uniqueConstraint annotation.

But a validation annotation may handle a validation error and give us
chance to manage duplicate record errors as easy as validation.

For instance a username field should be @Required, @MaxSize(value =
XX) and @Unique.
If client try to save a duplicate record. Will see the
validation.unique multilingual error.

2009/11/24 Guillaume Bort <guillau...@gmail.com>:
--
FIRAT KÜÇÜK

Guillaume Bort

unread,
Nov 24, 2009, 10:12:18 AM11/24/09
to play-fr...@googlegroups.com
Well I think it could be a little tricky. Perhaps you can do the same
using a custom check and the new @CheckWith annotation ?

2009/11/24 Fırat KÜÇÜK <firat...@gmail.com>:

Fırat KÜÇÜK

unread,
Nov 24, 2009, 10:22:27 AM11/24/09
to play-fr...@googlegroups.com
It is not just related to me. An additional annotation may be helpfull
for everyone.
Otherwise i can use @CheckWith or manually get the count of items and
show a related
validation error. But i guess nothing of these will be easier than an
annotation.


2009/11/24 Guillaume Bort <guillau...@gmail.com>:

Guillaume Bort

unread,
Nov 24, 2009, 10:27:28 AM11/24/09
to play-fr...@googlegroups.com
Yes I understand but it isn't a simple annotation. It require to do
some JPA queries, potentially some joins.

For now it is not in the spirit of the validation framework as it
operates on simple Java objects. The @CheckWith annotation has been
added to allow more 'functional' validations. And a uniqueness check
seems a functional validation from my point of view.

2009/11/24 Fırat KÜÇÜK <firat...@gmail.com>:

Fırat KÜÇÜK

unread,
Nov 24, 2009, 10:38:14 AM11/24/09
to play-fr...@googlegroups.com
Ok i'll go the @CheckWith way.

2009/11/24 Guillaume Bort <guillau...@gmail.com>:

Guillaume Bort

unread,
Nov 24, 2009, 10:43:53 AM11/24/09
to play-fr...@googlegroups.com
Ok and let me know if it works. Because there is some potential
problems between the validationPlugin and JPAPlugin.
>>> fram...@googlegroups.com.

Fırat KÜÇÜK

unread,
Nov 24, 2009, 10:53:45 AM11/24/09
to play-fr...@googlegroups.com
Beyond this there is other trouble to implement such a feature.
@Unique or a @CheckWith annotation may be useful when we create a record.
But updating will be laborious.

Let's go back to the user sample. username should be unique when we
create a user record.
But when we update the record. username will be the same as we expect.
So validation fails.

So validation should behave different in update.

2009/11/24 Guillaume Bort <guillau...@gmail.com>:
FIRAT KÜÇÜK

Fırat KÜÇÜK

unread,
Nov 24, 2009, 11:01:32 AM11/24/09
to play-fr...@googlegroups.com
May be a profiled annotation system may accomplish this :)
But this is far from this topic.

@Required
@Profiles(
profiles = {
@Profile(name = "update", annotations = {@Unique})
}
)
public String username;

Whatever, as you said it is more functional as i thought.


24 Kasım 2009 17:53 tarihinde Fırat KÜÇÜK <firat...@gmail.com> yazdı:
--
FIRAT KÜÇÜK

Guillaume Bort

unread,
Nov 24, 2009, 11:19:00 AM11/24/09
to play-fr...@googlegroups.com
You can easily determine in your own check if it is a creation or an
update: check if the id field is set or not.

2009/11/24 Fırat KÜÇÜK <firat...@gmail.com>:

Tomas

unread,
Nov 24, 2009, 11:40:03 AM11/24/09
to play-framework
Hi, I have implemented exactly this validation, I thought I'll post it
when the module repository is done. It works for insert and also
update, and you can specify in the annotation if the field should be
globally unique or, when you have a 1:n relation, the field could be
unique only if the owner entity is the same.
e.g:
@Unique(message = "person.validation.unique")
public String name;
,
@ManyToOne
@JoinColumn(nullable = false)
public Project project;
@Unique(additionalHQL = "o.project=?", additionalObjects =
{ "project" })
public String name;
here's the code:

package validation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.persistence.Query;

import org.apache.commons.lang.StringUtils;

import net.sf.oval.Validator;
import net.sf.oval.configuration.annotation.AbstractAnnotationCheck;
import net.sf.oval.configuration.annotation.Constraint;
import net.sf.oval.context.FieldContext;
import net.sf.oval.context.OValContext;
import play.db.jpa.JPA;
import play.db.jpa.Model;

@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD, ElementType.PARAMETER })
@Constraint(checkWith = Unique.UniqueCheck.class)
public @interface Unique {
String message() default UniqueCheck.mes;

String additionalHQL() default "";

String[] additionalObjects() default {};

public static class UniqueCheck extends
AbstractAnnotationCheck<Unique> {

public static final String mes = "validation.unique";

private String additionalHQL;
private String[] additionalObjects;

@Override
public void configure(Unique unique) {
setMessage(unique.message());
additionalHQL = unique.additionalHQL();
additionalObjects = unique.additionalObjects();
}

public boolean isSatisfied(Object validatedObject, Object value,
OValContext context,
Validator validator) {
if (value == null || value.toString().length() == 0) {
return false;
}
Model validatedModel = (Model) validatedObject;
String field = ((FieldContext) context).getField().getName();
StringBuffer hql = new StringBuffer();
hql.append("SELECT COUNT(*) FROM ");
hql.append(validatedObject.getClass().getSimpleName());
hql.append(" AS o WHERE o.");
hql.append(field);
hql.append("=?");
if (validatedModel.id != null)
hql.append(" AND id IS NOT ?");
if (additionalHQL.length() > 0) {
hql.append(" AND ");
hql.append(additionalHQL);
}
Query query = JPA.em().createQuery(hql.toString());
int index = 1;
query.setParameter(index++, value);
if (validatedModel.id != null)
query.setParameter(index++, validatedModel.id);
for (String additionalObject : additionalObjects) {
String methodName = "get" + StringUtils.capitalize
(additionalObject);
try {
Object val = validatedObject.getClass().getMethod
(methodName).invoke(validatedObject);
query.setParameter(index++, val);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Long count = (Long) query.getSingleResult();
return count.equals(0l);
}
}
}



On Nov 24, 5:19 pm, Guillaume Bort <guillaume.b...@gmail.com> wrote:
> You can easily determine in your own check if it is a creation or an
> update: check if the id field is set or not.
>
> 2009/11/24 Fırat KÜÇÜK <firatku...@gmail.com>:
>
>
>
> > May be a profiled annotation system may accomplish this :)
> > But this is far from this topic.
>
> > @Required
> > @Profiles(
> >  profiles = {
> >    @Profile(name = "update", annotations = {@Unique})
> >  }
> > )
> > public String username;
>
> > Whatever, as you said it is more functional as i thought.
>
> > 24 Kasım 2009 17:53 tarihinde Fırat KÜÇÜK <firatku...@gmail.com> yazdı:
> >> Beyond this there is other trouble to implement such a feature.
> >> @Unique or a @CheckWith annotation may be useful when we create a record.
> >> But updating will be laborious.
>
> >> Let's go back to the user sample. username should be unique when we
> >> create a user record.
> >> But when we update the record. username will be the same as we expect.
> >> So validation fails.
>
> >> So validation should behave different in update.
>
> >> 2009/11/24 Guillaume Bort <guillaume.b...@gmail.com>:
> >>> Ok and let me know if it works. Because there is some potential
> >>> problems between the validationPlugin and JPAPlugin.
>
> >>> On 24 nov. 2009, at 16:22, Fırat KÜÇÜK <firatku...@gmail.com> wrote:
>
> >>>> It is not just related to me. An additional annotation may be helpfull
> >>>> for everyone.
> >>>> Otherwise i can use @CheckWith or manually get the count of items and
> >>>> show a related
> >>>> validation error. But i guess nothing of these will be easier than an
> >>>> annotation.
>
> >>>> 2009/11/24 Guillaume Bort <guillaume.b...@gmail.com>:
> >>>>> Well I think it could be a little tricky. Perhaps you can do the same
> >>>>> using a custom check and the new @CheckWith annotation ?
>
> >>>>> 2009/11/24 Fırat KÜÇÜK <firatku...@gmail.com>:
> >>>>>> In fact a JPA based @uniqueConstraint annotation give us the ability
> >>>>>> to define the constraints.
> >>>>>> It is not much more than a definition. And when we try to save a
> >>>>>> duplicate entry. We will get the same exception
> >>>>>> before writing @uniqueConstraint annotation.
>
> >>>>>> But a validation annotation may handle a validation error and give
> >>>>>> us
> >>>>>> chance to manage duplicate record errors as easy as validation.
>
> >>>>>> For instance a username field should be @Required, @MaxSize(value =
> >>>>>> XX) and @Unique.
> >>>>>> If client try to save a duplicate record. Will see the
> >>>>>> validation.unique multilingual error.
>
> >>>>>> 2009/11/24 Guillaume Bort <guillaume.b...@gmail.com>:
> >>>>>>> Do you mean a unique value in the database ? I think that you
> >>>>>>> should
> >>>>>>> look at a JPA annotation.
>
> >>>>>>> 2009/11/24 Fırat KÜÇÜK <firatku...@gmail.com>:
> >>>>>>>> Hi,
> >>>>>>>> I looked for any way to check annotation based restriction for
> >>>>>>>> unique values?
> >>>>>>>> Is @Unique or some annotation like that convenient for validation?
>
> >>>>>>>> --
> >>>>>>>> FIRAT KÜÇÜK
>
> >>>>>>>> --
>
> >>>>>>>> You received this message because you are subscribed to the
> >>>>>>>> Google Groups "play-framework" group.
> >>>>>>>> To post to this group, send email to play-fr...@googlegroups.com
> >>>>>>>> .
> >>>>>>>> To unsubscribe from this group, send email to play-framewor...@googlegroups.com
> >>>>>>>> .
> >>>>>>>> For more options, visit this group athttp://groups.google.com/group/play-framework?hl=en
> >>>>>>>> .
>
> >>>>>>> --
>
> >>>>>>> You received this message because you are subscribed to the
> >>>>>>> Google Groups "play-framework" group.
> >>>>>>> To post to this group, send email to play-fr...@googlegroups.com
> >>>>>>> .
> >>>>>>> To unsubscribe from this group, send email to play-framewor...@googlegroups.com
> >>>>>>> .
> >>>>>>> For more options, visit this group athttp://groups.google.com/group/play-framework?hl=en
> >>>>>>> .
>
> >>>>>> --
> >>>>>> FIRAT KÜÇÜK
>
> >>>>>> --
>
> >>>>>> You received this message because you are subscribed to the Google
> >>>>>> Groups "play-framework" group.
> >>>>>> To post to this group, send email to play-
> >>>>>> fram...@googlegroups.com.
> >>>>>> To unsubscribe from this group, send email to play-framewor...@googlegroups.com
> >>>>>> .
> >>>>>> For more options, visit this group athttp://groups.google.com/group/play-framework?hl=en
> >>>>>> .
>
> >>>>> --
>
> >>>>> You received this message because you are subscribed to the Google
> >>>>> Groups "play-framework" group.
> >>>>> To post to this group, send email to play-fr...@googlegroups.com.
> >>>>> To unsubscribe from this group, send email to play-framewor...@googlegroups.com
> >>>>> .
> >>>>> For more options, visit this group athttp://groups.google.com/group/play-framework?hl=en
> >>>>> .
>
> >>>> --
> >>>> FIRAT KÜÇÜK
>
> >>>> --
>
> >>>> You received this message because you are subscribed to the Google
> >>>> Groups "play-framework" group.
> >>>> To post to this group, send email to play-fr...@googlegroups.com.
> >>>> To unsubscribe from this group, send email to play-framewor...@googlegroups.com
> >>>> .
> >>>> For more options, visit this group athttp://groups.google.com/group/play-framework?hl=en
> >>>> .
>
> >>> --
>
> >>> You received this message because you are subscribed to the Google Groups "play-framework" group.
> >>> To post to this group, send email to play-fr...@googlegroups.com.
> >>> To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
> >>> For more options, visit this group athttp://groups.google.com/group/play-framework?hl=en.

Michal Mach

unread,
Nov 24, 2009, 2:10:24 PM11/24/09
to play-fr...@googlegroups.com
Are there some examples of usage?

2009/11/24 Guillaume Bort <guillau...@gmail.com>
Reply all
Reply to author
Forward
0 new messages