[
http://opensource.atlassian.com/projects/hibernate/browse/HV-482?page=com...
]
Tim Canavan edited comment on HV-482 at 6/7/11 3:27 AM:
--------------------------------------------------------
Thanks for the reply
We are using method validation through a MethodInterceptor for the service methods. We are
using the exact same interceptor for the unit tests
and applying it to exactly the same service methods. All parameter validation is at the
interface level.
So it works for OpenEJB and not for Weblogic.
Our interceptor works fine with beta1 where the ConstraintDeclarationException is not
thrown. We need to solve this as
without a fix we cannot update to future versions ofthe HV
See code below
Tim
{code}
// Interceptor code
import java.util.Set;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.method.MethodConstraintViolation;
import org.hibernate.validator.method.MethodConstraintViolationException;
import org.hibernate.validator.method.MethodValidator;
public class MethodValidationInterceptor {
@AroundInvoke
// CHECKSTYLE:OFF IllegalThrows -- we have to declare it because of interceptors API
public Object invoke(final InvocationContext invocationContext) throws Exception {
Validator validator =
Validation.byProvider(HibernateValidator.class).configure().traversableResolver(new
CustomTraversableResolver()).buildValidatorFactory().getValidator();
final MethodValidator methodValidator = validator.unwrap(MethodValidator.class);
Set<MethodConstraintViolation<Object>> validationMessages =
methodValidator.validateAllParameters(
invocationContext.getTarget(), invocationContext.getMethod(),
invocationContext.getParameters(), new Class[]{});
if (!validationMessages.isEmpty()) {
throw new MethodConstraintViolationException(validationMessages);
}
final Object returnValue = invocationContext.proceed();
validationMessages =
methodValidator.validateReturnValue(invocationContext.getTarget(),
invocationContext.getMethod(), returnValue);
if (!validationMessages.isEmpty()) {
throw new MethodConstraintViolationException(validationMessages);
}
return returnValue;
}
}
//Custom Traversable Provider to ignore all other
// persistence proviers other than hibernate.
public class CustomTraversableResolver implements TraversableResolver {
public boolean isLoaded(Object entity, String attributeName) {
final List<PersistenceProvider> providers =
PersistenceProviderResolverHolder.getPersistenceProviderResolver()
.getPersistenceProviders();
for (PersistenceProvider provider : providers) {
if (provider instanceof HibernatePersistence) {
final LoadState state =
provider.getProviderUtil().isLoadedWithoutReference(entity, attributeName);
if (state == LoadState.UNKNOWN) {
continue;
}
return state == LoadState.LOADED;
}
}
for (PersistenceProvider provider : providers) {
if (provider instanceof HibernatePersistence) {
final LoadState state =
provider.getProviderUtil().isLoadedWithReference(entity, attributeName);
if (state == LoadState.UNKNOWN) {
continue;
}
return state == LoadState.LOADED;
}
}
return true;
}
public boolean isReachable(Object traversableObject, Path.Node traversableProperty,
Class rootBeanType,
Path pathToTraversableObject, ElementType elementType) {
// we have to check traversableProperty.getName() against null to check
// the root gets validated (see HV-266)
// also check the element type, if it is ElementType.TYPE then we don't
// have to call is reachable since we have
// a class level constraint (HV-305)
if (traversableObject == null
|| traversableProperty.getName() == null ||
ElementType.TYPE.equals(elementType)) {
return true;
}
return isLoaded(traversableObject, traversableProperty.getName());
}
public boolean isCascadable(Object object, Path.Node node, Class cls, Path path,
ElementType elementType) {
return true;
}
}
// EJB Service
public interface CustomerService {
void saveCustomer(@NotNull RequestContext requestContent,@NotNull Customer customer);
}
//EJB Implmentation bean
@Remote
@Stateless(mappedName = "CustomerService", name = "CustomerService")
@Interceptors({MethodValidationInterceptor.class, RequestContextInterceptor.class,
LoggingInterceptor.class})
public class CustomerServiceBean implements CustomerService {
void saveCustomer(RequestContect ctx,Customer customer) {
//......
}
}
{code}
was (Author: tcanavan):
Thanks for the reply
We are using method validation through a MethodInterceptor for the service methods. We are
using the exact same interceptor for the unit tests
and applying it to exactly the same service methods. All parameter validation is at the
interface level.
So it works for OpenEJB and not for Weblogic.
Our interceptor works fine with beta1 where the ConstraintDeclarationException is not
thrown. We need to solve this as
without a fix we cannot update to future versions ofthe HV
See code below
Tim
{code}
// Interceptor code
import java.util.Set;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.method.MethodConstraintViolation;
import org.hibernate.validator.method.MethodConstraintViolationException;
import org.hibernate.validator.method.MethodValidator;
public class MethodValidationInterceptor {
@AroundInvoke
// CHECKSTYLE:OFF IllegalThrows -- we have to declare it because of interceptors API
public Object invoke(final InvocationContext invocationContext) throws Exception {
Validator validator =
Validation.byProvider(HibernateValidator.class).configure().traversableResolver(new
CustomTraversableResolver()).buildValidatorFactory().getValidator();
final MethodValidator methodValidator = validator.unwrap(MethodValidator.class);
Set<MethodConstraintViolation<Object>> validationMessages =
methodValidator.validateAllParameters(
invocationContext.getTarget(), invocationContext.getMethod(),
invocationContext.getParameters(), new Class[]{});
if (!validationMessages.isEmpty()) {
throw new MethodConstraintViolationException(validationMessages);
}
final Object returnValue = invocationContext.proceed();
validationMessages =
methodValidator.validateReturnValue(invocationContext.getTarget(),
invocationContext.getMethod(), returnValue);
if (!validationMessages.isEmpty()) {
throw new MethodConstraintViolationException(validationMessages);
}
return returnValue;
}
}
//Custom Traversable Provider to ignore all other
// persistence proviers other than hibernate.
public class CustomTraversableResolver implements TraversableResolver {
public boolean isLoaded(Object entity, String attributeName) {
final List<PersistenceProvider> providers =
PersistenceProviderResolverHolder.getPersistenceProviderResolver()
.getPersistenceProviders();
for (PersistenceProvider provider : providers) {
if (provider instanceof HibernatePersistence) {
final LoadState state =
provider.getProviderUtil().isLoadedWithoutReference(entity, attributeName);
if (state == LoadState.UNKNOWN) {
continue;
}
return state == LoadState.LOADED;
}
}
for (PersistenceProvider provider : providers) {
if (provider instanceof HibernatePersistence) {
final LoadState state =
provider.getProviderUtil().isLoadedWithReference(entity, attributeName);
if (state == LoadState.UNKNOWN) {
continue;
}
return state == LoadState.LOADED;
}
}
return true;
}
public boolean isReachable(Object traversableObject, Path.Node traversableProperty,
Class rootBeanType,
Path pathToTraversableObject, ElementType elementType) {
// we have to check traversableProperty.getName() against null to check
// the root gets validated (see HV-266)
// also check the element type, if it is ElementType.TYPE then we don't
// have to call is reachable since we have
// a class level constraint (HV-305)
if (traversableObject == null
|| traversableProperty.getName() == null ||
ElementType.TYPE.equals(elementType)) {
return true;
}
return isLoaded(traversableObject, traversableProperty.getName());
}
public boolean isCascadable(Object object, Path.Node node, Class cls, Path path,
ElementType elementType) {
return true;
}
}
// EJB Service
public interface CustomerService {
void saveCustomer(@NotNull RequestContext requestContent,@NotNull Customer customer);
}
//EJB Implmentation bean
@Remote
@Stateless(mappedName = "LovCodeService", name = "LovCodeService")
@Interceptors({MethodValidationInterceptor.class, RequestContextInterceptor.class,
LoggingInterceptor.class})
public class CustomerServiceBean implements CustomerService {
void saveCustomer(RequestContect ctx,Customer customer) {
//......
}
}
{code}
Weblogic ConstrantDeclationException HVbeta2
--------------------------------------------
Key: HV-482
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HV-482
Project: Hibernate Validator
Issue Type: Bug
Affects Versions: 4.2.0.Beta2
Environment: Weblogic 10.3
Reporter: Tim Canavan
After upgrading to HV beta2 and changing all our validations to be at the interface
level
we get the constraint declaration exception
Caused by: javax.validation.ConstraintDeclarationException: Only the root method of an
overridden method in an inheritance hierarchy may be annotated with parameter constraints.
The following method itself has no parameter constraints but it is not defined on a
sub-type of class
Under OpenEJB which our unit tests use everything works fine.
Is there any code that HV could use that would allow it to understand these proxies or
would an option be available
to turn the check off.
--
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