More useful exception error messages
------------------------------------
Key: HV-235
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HV-235
Project: Hibernate Validator
Issue Type: Improvement
Affects Versions: 4.0.0.CR1
Reporter: Ken Egervari
Hi, i know you are aware of this for version 3.1, but the problem has become even worse in
4.0 CR1.
Whenever an example is thrown, it looks like this:
javax.validation.ConstraintViolationException: Invalid object at persist time for groups
[javax.validation.groups.Default, ]
at
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:83)
at
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:51)
at
org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:142)
at
org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:65)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at
org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
at
org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at
org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:538)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:530)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:526)
at
org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:740)
at
org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
at
org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at
org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:737)
Now, as I mentioned before, this gives unit tests absolutely no clue what the problem is.
You see, when people get these exceptions... it's just not when they are testing their
constraints - it's when they are testing their database, or their controllers. Usually
the point of these tests is to test OTHER things, not the constraints. Yes, I am happy
they are working nicely... but my main objective is to quickly fix the bean so the
constraint doesn't fail and go along my merry way.
As it stands, these error messages are a pain in the rear. It's even worse now because
you're not even telling us which object it occured on... so if we stored an object
with lots of cascading children, there is no telling what the heck went wrong.
In a unit test, this is a very common idiom:
try {
userAccountDao.save( userAccount );
clear();
} catch( ConstraintViolationException e ) {
for( ConstraintViolation constraintViolation : e.getConstraintViolations() ) {
System.out.println( constraintViolation.getMessage() );
System.out.println( constraintViolation.getInvalidValue() );
System.out.println( constraintViolation.getLeafBean() );
System.out.println( constraintViolation.getMessageTemplate() );
System.out.println( constraintViolation.getConstraintDescriptor() );
System.out.println( constraintViolation.getPropertyPath() );
System.out.println( constraintViolation.getRootBeanClass() );
}
}
This is just trash code to write every time a constraint unmistakably gets violated. I
tried in Junit... and there's no way to wrap a test method with another method to
catch the exception and print this - like an aop around my unit tests.
Now, there are 2 solutions.
1) Rewrite the example to something like this:
javax.validation.ConstraintViolationException: object of class
jawbs.domain.user.UserAccount has constraint violations [ ( property:
"emailAddress", message: "Must be a valid email address" ) ]
at
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:83)
at
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:51)
at
org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:142)
at
org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:65)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
....
2) Have an option on the validation factory in Hibernate (i.e. not using build default
validator) to throw custom exceptions instead of the "standard" one. The custom
one can even be provided by the library.
The idea is that the developer shouldn't have to go through all these hoops just to
see error messages. Viewing the details of errors messages has been around in other
frameworks just fine. As it stands, this feature makes this library/framework very, very,
very, very frustrating to deal with. The actual error you guys are throwing... or the
genuises who wrote the standard... is the most useless exception I've read all year.
I'm sorry to be aggressive on this... I'm just so frustrated with it. Like REALLY
frustrated. I feel so powerless in that it's a part of your code I can't just swap
out easily without recompiling it. And I don't think that's the right solution.
3) If there has to be workaround, please make it a HUGE point in the 4.0 GA documentation.
Make sure people know about it and don't have to hunt down for it.
Thanks!
--
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....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira