[hibernate-issues] [Hibernate-JIRA] Commented: (HV-230) Database Connective or @Unique
Ken Egervari (JIRA)
noreply at atlassian.com
Fri Sep 25 09:22:50 EDT 2009
[ http://opensource.atlassian.com/projects/hibernate/browse/HV-230?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=34048#action_34048 ]
Ken Egervari commented on HV-230:
---------------------------------
Cool!
Here's an updated version I'm using for 4.0.0rc1:
{code}
public class QueryConstraintValidator implements ConstraintValidator<QueryConstraint,DomainObject> {
/* Fields */
private static Logger logger =
LoggerFactory.getLogger( QueryConstraintValidator.class );
private String hql;
private boolean enabled;
/* Services */
public void initialize( QueryConstraint queryConstraint ) {
this.hql = queryConstraint.hql();
this.enabled = queryConstraint.enabled();
}
public boolean isValid( DomainObject domainObject ) {
return isValid( domainObject, null );
}
public boolean isValid( DomainObject domainObject, ConstraintValidatorContext context ) {
BeanWrapper beanWrapper = new BeanWrapperImpl( domainObject );
SessionFactory sessionFactory =
( SessionFactory ) ApplicationContextProvider.getBean( "sessionFactory" );
if( enabled && sessionFactory != null ) {
logger.debug( "Enabled - Validating constraint with: " );
logger.debug( hql );
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery(
HqlParser.removePeriodsFromParameterNames( hql )
);
for( String parameterName : HqlParser.getParameterNames( hql ) ) {
query.setParameter(
HqlParser.removePeriodsFromParameterName( parameterName ),
beanWrapper.getPropertyValue( parameterName )
);
}
boolean result = (Long) query.uniqueResult() == 0;
logger.debug( "isValid is returning: " + result );
tx.commit();
session.close();
return result;
}
return true;
}
}
{code}
And here's the annotation:
{code}
@Constraint( validatedBy = QueryConstraintValidator.class )
@Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
@Documented
public @interface QueryConstraint {
String hql() default "";
String message() default "{validator.query}";
boolean enabled() default true;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
{code}
Of course all of this is spring-aware, but I'm sure my suggestions about extending base classes or implementing an interface and what not would replace that ;)
Thanks Hardy!
> Database Connective or @Unique
> ------------------------------
>
> Key: HV-230
> URL: http://opensource.atlassian.com/projects/hibernate/browse/HV-230
> Project: Hibernate Validator
> Issue Type: New Feature
> Components: validators
> Affects Versions: 3.1.0.GA
> Reporter: Ken Egervari
> Priority: Critical
> Fix For: 4.1.0
>
>
> I find a common validation use case is checking to see if a field is unique to all those in the table, such as emails, isbns, usernames, keywords, etc. these fields may not be the primary key, but still need to be unique.
> It would be fantastic if hibernate validator implemented this.
> This is a common problem though because the domain class will need to have access the database. I dunno if there's an easy way to wire in a copy of sessionFactory to make this easy to write.
> Perhaps something like this:
> @Query( "select user from User user where user.emailAddress = :this.emailAddress and user.id != :this.id", message = "That Email is already being used by another user in the system" )
> private String emailAddress;
> Basically the idea is that if @Query returns no results, then the validation constraint is good, and if returns more than 1 result, then it fails. Kind of like simpleJdbcTemplate.queryForMap() does within the Spring testing framework. That method causes the test to fail if no row is returned, because it expects 1 result.
> If it were possible to just say
> @Unique
> private String emailAddress;
> That would be extremely concise and would save people a ton of time.
> Of course, this requires some interoperability with Hibernate... but I think that's a good thing, no?
> Thanks for taking this into consideration. I'd appreciate an email letting me know how to do this in a clean way in 3.1.0 GA as it is as well if you would. Thank you.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the hibernate-issues
mailing list