[
http://opensource.atlassian.com/projects/hibernate/browse/HV-524?page=com...
]
Nicholas Padilla commented on HV-524:
-------------------------------------
Hey ladies and gents! I have worked on this a bit today and here are my findings:
When defining a @Constraint implementation AND specifying ElementType.TYPE usage you can
end up in a scenario where BeanMetaDataImpl doesn't know how to build the
ValueContext for the field. Since in some cases, like @ScriptAssert, you are not really
looking for specific Member/PropertyPath to lookup.
This happens because this line
{code:borderStyle=solid}
initClassConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores,
BeanMetaDataCache beanMetaDataCache)
{code}
calls
{code:borderStyle=solid}
BeanMetaDataImpl [line: 715] - initClassConstraints(Class<?>, AnnotationIgnores,
BeanMetaDataCache)
{code}
which intentionally creates a NULL Member - which we try to use later as a propertyName.
This is correct since this constraint is of ElementType.TYPE.
It then reaches this point in the code:
{code:borderStyle=solid}
ValidatorImpl [line: 137] - validate(T, Class<?>...)
{code}
The ValueContext gets created with an empty Path object, next:
{code:borderStyle=solid}
ValidatorImpl [line: 444] - validateConstraint(ValidationContext<T, ?>,
ValueContext<U, V>, BeanMetaConstraint<?>)
{code}
This call tries to set our Path to be correct, using the Parent and the propertyName(),
however, we have an ElementType.TYPE so we don't set it. Nothing to set either since
we create a NULL Member earlier. Next:
{code:borderStyle=solid}
BeanValidationListener$AutomaticLifeCycleValidationTraversableResolver [line: 123] -
isReachable(Object, Node, Class<?>, Path, ElementType)
{code}
This call expects a non-null and non-empty Path object, but guess what? It is still empty.
So when it calls isValidationRequired() a few lines down it bombs with the error below;
this is because there is nothing to call .next() on.
{noformat}
Caused by: java.util.NoSuchElementException
at java.util.Collections$EmptyIterator.next(Collections.java:2998)
at
org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener$AutomaticLifeCycleValidationTraversableResolver.isRootObjectPath(BeanValidationListener.java:180)
at
org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener$AutomaticLifeCycleValidationTraversableResolver.isReachable(BeanValidationListener.java:123)
at
org.hibernate.validator.engine.resolver.SingleThreadCachedTraversableResolver.isReachable(SingleThreadCachedTraversableResolver.java:46)
at
org.hibernate.validator.engine.ValidatorImpl.isValidationRequired(ValidatorImpl.java:1242)
... 70 more
{noformat}
*ALSO: one major note - this only errors out when trying to call .persist using
EclipseLink, when using the @Valid from Spring MVC it works as expected.*
I hope this helps in resolving this issue, let mr know if there are any questions - I am
tired now so I may not be firing on enough cylinders to get all this
out the way it should be. :)
Please see my log file that contains a full logging of this problem.
java.util.NoSuchElementException in type level validation using
EclipseLink
---------------------------------------------------------------------------
Key: HV-524
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HV-524
Project: Hibernate Validator
Issue Type: Bug
Components: validators
Affects Versions: 4.2.0.Final
Environment: EclipseLink 2.2.0
Reporter: sinuhepop
Attachments: HV-524.zip
When EclipseLink obtains an entity from database does a validation. It works ok with
field level validators, but throws an exception with type level ones.
The problem is that SingleThreadCachedTraversableResolver sends an "empty"
pathToTraversableObject to EL's BeanValidationListener, who finally fails when calling
"pathToTraversableObject.iterator().next().getName()".
I don't know who (HV or EL) is responsible of the issue, but it worked with
HV-4.0.2.GA.
Thanks for your effort.
Sinuhé.
{noformat}
Caused by: javax.validation.ValidationException: Call to
TraversableResolver.isReachable() threw an exception
at
org.hibernate.validator.engine.ValidatorImpl.isValidationRequired(ValidatorImpl.java:1251)
~[hibernate-validator-4.2.0.Final.jar:4.2.0.Final]
at
org.hibernate.validator.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:448)
~[hibernate-validator-4.2.0.Final.jar:4.2.0.Final]
at
org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:397)
~[hibernate-validator-4.2.0.Final.jar:4.2.0.Final]
at
org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:361)
~[hibernate-validator-4.2.0.Final.jar:4.2.0.Final]
at
org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:313)
~[hibernate-validator-4.2.0.Final.jar:4.2.0.Final]
at org.hibernate.validator.engine.ValidatorImpl.validate(ValidatorImpl.java:139)
~[hibernate-validator-4.2.0.Final.jar:4.2.0.Final]
at
org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.validateOnCallbackEvent(BeanValidationListener.java:84)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.preUpdate(BeanValidationListener.java:72)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:671)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:641)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:200)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChanges(DeferredChangeDetectionPolicy.java:85)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChangesForExistingObject(DeferredChangeDetectionPolicy.java:54)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:623)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1496)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:264)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1130)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
... 73 common frames omitted
Caused by: java.util.NoSuchElementException: null
at java.util.Collections$EmptyIterator.next(Unknown Source) ~[na:1.7.0]
at
org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener$AutomaticLifeCycleValidationTraversableResolver.isRootObjectPath(BeanValidationListener.java:180)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener$AutomaticLifeCycleValidationTraversableResolver.isReachable(BeanValidationListener.java:123)
~[eclipselink-2.2.0.jar:2.2.0.v20110202-r8913]
at
org.hibernate.validator.engine.resolver.SingleThreadCachedTraversableResolver.isReachable(SingleThreadCachedTraversableResolver.java:46)
~[hibernate-validator-4.2.0.Final.jar:4.2.0.Final]
at
org.hibernate.validator.engine.ValidatorImpl.isValidationRequired(ValidatorImpl.java:1242)
~[hibernate-validator-4.2.0.Final.jar:4.2.0.Final]
... 90 common frames omitted
{noformat}
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira