Hibernate: MethodConstraintViolation is deprecated - java

I see also from the jboss doc that https://docs.jboss.org/hibernate/validator/4.3/api/org/hibernate/validator/method/MethodConstraintViolationException.html is deprecated, however it does not specify with what it has been substituted.
Anybody knows?

First at all, Deprecation doesn't mean that it does not work. If you take a look at the Hibernate Validator Migration Guide will see the next evolution of method validator, that clarifies there is no alternative in your case,
For version 4.3
The package org.hibernate.validator.method with its containing classes
is deprecated without alternative for now. In Hibernate Validator 5
this package will be removed to align with Bean Validation 1.1. The
method level validation methods will then be available via
javax.validation.Validator.
Here is the deprecation list for Hibernate Validator 4.3.
If we continue with version 5.0.x, there is more info about it,
The custom method validation feature has been replaced by the method
validation specfied by Bean Validation 1.1.
Methods for method validation moved from javax.validation.Validator to
MethodValidator (BVAL-310, HV-629)
Renamed javax.validation.MethodValidator to ExecutableValidator; javax.validation.Validator#forMethods() renamed to forExecutables() (BVAL-355).
The road shows that method validation of parameters and return values had been standardized as part of Bean Validation 1.1 and Hibernate Validator 5 final releases support it.
Now if you want to migrate to HV5/BV1.1, I suggest you to follow the HV5 documentation (maybe you want to go directly to Declaring and validating method constraints section)

In Javadoc it says that
... Will by replaced by equivalent functionality defined by the Bean Validation 1.1 API as of Hibernate Validator 5.

Related

JSR 303 - How to get validator instance programmatically by annotation?

I could not find a way to apply a constraint conditionally, so I would like to make a validator that applies other annotations conditionally. I would like to be able to do:
#IfNotNull(validateWith = Email.class)
Then in my validator class, get the annotation classes from validateWith, get their validator instances, and validate via those if this value is not null. Unfortunately, I don't see a way to lookup a Validator instance by annotation.
Is there a way to do that or apply a constraint conditionally?
I am using Hibernate as the validation provider.

How to use Integrator service in Hibernate 5 for adding annotated classes

This is with reference to JPA 2.0: Adding entity classes to PersistenceUnit *from different jar* automatically and Unable to call Hibernate/QueryDSL from another maven subproject
It seems that Hibernate 4 had a great way to dynamically load entity classes using
org.hibernate.integrator.spi.Integrator service.
Now when using Hibernate 5, the Integrator interface's integrate method gives me
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry)
{
}
Where metadata is of type org.hibernate.boot.Metadata
I am unable to call addAnnotatedClass(), neither I am able to obtain the original Configuration object that was there in Hibernate 4.
How do I get around with this?
I am using maven and jetty.
I am not using spring (so please do not provide any spring based solution)
This was actually related to something I was wrestling with over the weekend in getting caught up on Hibernate 5. You can read about the planned changes related to the Configuration class in the latest Javadoc for Hibernate 4. The new place for getting info on all loaded entity classes including annotated entities is the Metadata class you mentioned. It has a getEntityBindings() method that will return the PersistentClass entity metadata representation for known all entities. This Collection is immutable however.
Recommendation is that you rethink using an Integrator to add entity bindings at runtime. This may have worked in the past, but the docs clearly point towards that not being intentional as this should be done at the time of initialization. The Metadata and SessionFactoryImplementor are for the most part immutable once built, and so the Integrator's intended purpose is not to modify these configuration items but instead use them as information on how to configure new Service integrations using the SessionFactoryServiceRegistry.
And if you're finding it annoying to configure your Session to find all your annotated classes at runtime, I suggest you try using the EntityManagerFactory approach for initializing Hibernate as it is far more straightforward and uses standard JPA syntax that can be switched to a handful of other providers if you ever need to. This will automatically scan for annotated entities on your behalf. The API is a bit more simplified and limited, but if you really ever need the power of native Hibernate-specific functionality there is a way to access the native underlying API.

JPA2 data validation verbose logging

I'm using EclipseLink 2.5 with JPA 2.1 in standalone java application.
Some field are marked with #Basic(optional=false), but even with null value I didn't get any error before commit. The constraint is set on database so I got a JDBC exception.
Adding Hibernate Validator to project and setting validation mode to callback didn't help.
Only with #NotNull annotation on field I got exception: javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details. which is not very specific and does not inform where the problem is.
I would like to know if there is any way to make this message look more robust: like field name not set or something like this and force eclipselink to check optional=false.
EDIT:
I know the difference between JPA and Bean Validation. I am trying to perform validation with JPA only, using optional=false. As far as I know (#Basic(optional = false) vs #Column(nullable = false) in JPA) #Basic(optional=false) should be checked at runtime and #Column(nullable=false) should be used to make column nonnullable in the database.
I'm looking for a method to display violations with out catching ConstraintViolations everywhere.
A couple of things here. First of you have to distinguish between JPA and Bean Validation. Two different specifications and things. #Basic is a JPA annotation whereas #NotNull is a Bean Validation annotation. Using #Basic(optional=false) in conjunction with schema creation you will indeed get a database constraint which in turn lead to a JDBC exception during persist.
By introducing Bean Validation you activate the JPA integration of Bean Validation. In this case prior to writing to the database the data will be validated via Bean Validation. In this case as part of pre-persist. As per specification a ConstraintViolationException is thrown in this case. You can call ConstraintViolationException.getConstraintViolations to get a set of the failing constraints. It is up to you to catch this exception and do the unwrapping yourself.
I'm looking for a method to display violations with out catching ConstraintViolations everywhere.
You could add a catch(ConstraintViolationException cve) {...} block at the outermost level of your application code (e.g. in form of some request handler/interceptor in case this is a web application) and use that to handle constraint violations in a generic way. The ConstraintViolation object provides lots of information such as the name of the concerned property etc. I'm not sure though why EclipseLink doesn't consider #Basic(optional=false), though.

How to enable #Required?

How to enable the #Required annotation in Java (Spring 3.1) ? Not in a xml, but in through Java. Also under which annotation I put this enabling? Under #Feature (in #FutureConfiguration or #Bean (in #Configuration) ?
Edit:
#Feature
public MvcAnnotationDriven annotationDriven(ConversionService conversionService) {
return new MvcAnnotationDriven().conversionService(conversionService)
.argumentResolvers(new CustomArgumentResolver());
}
Does this enables all annotations?
#anubhava's answer works, but he's referenced the Spring 2.0 manual, which is 5 years old.
In XML config, Spring 3.x has a more elegant approach: <context:annotation-config/>. This also enabled a whole other bunch of features that you'll probably want, whereas RequiredAnnotationBeanPostProcessor only enables a few.
See Spring 3.x manual.
If you're using #Bean-style config, then annotations like #Required should already be enabled, since that's how #Bean works. However, it's possible that this is a bug - Spring 3.1 is still in early beta, and big chunks of it are likely to be broken.
Unless you really know what you're doing, I strongly recommend sticking to 3.0.x.
From the Spring manual:
There is one last little (small, tiny)
piece of Spring configuration that is
required to actually 'switch on' this
behavior. Simply annotating the
'setter' properties of your classes is
not enough to get this behavior. You
need to enable a component that is
aware of the #Required annotation and
that can process it appropriately.
This component is the
RequiredAnnotationBeanPostProcessor
class. This is a special
BeanPostProcessor implementation that
is #Required-aware and actually
provides the 'blow up if this required
property has not been set' logic. It
is very easy to configure; simply drop
the following bean definition into
your Spring XML configuration.
<bean class=
"org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
Please check: http://static.springsource.org/spring/docs/2.0.x/reference/metadata.html
Use AnnotationConfigApplicationContext if you don't want to use XML:
Standalone application context,
accepting annotated classes as input -
in particular #Configuration-annotated
classes, but also plain #Components
and JSR-330 compliant classes using
javax.inject annotations. Allows for
registering classes one by one
(register(java.lang.Class...)) as well
as for classpath scanning
(scan(java.lang.String...)).
In case of multiple Configuration
classes, Bean methods defined in later
classes will override those defined in
earlier classes. This can be leveraged
to deliberately override certain bean
definitions via an extra Configuration
class.
Sample Code:
ConfigurableApplicationContext applicationContext =
new AnnotationConfigApplicationContext(
"com.mycompany.package1",
"com.mycompany.package2",
"com.mycompany.package3"
// etc.
);
applicationContext.refresh();

Is there a standard way to enable JSR 303 Bean Validation using annotated method arguments

I've been looking a around for a while now with no luck. I'n not using Spring MVC but still want to use #javax.validation.Valid to enable validation of method arguments. To give an example
public class EventServiceImpl implements IEventService {
#Override
public void invite(#Valid Event event, #Valid User user) { ... }
}
Using MVC, this is enabled for #Controller annotated beans with a simple <mvc:annotation-driven/> (see 5.7.4.3 Configuring a JSR-303 Validator for use by Spring MVC).
Using AOP should be quite trivial. Nevertheless, I suspect there's some standard way to do this. Hence the question: Is there a similar thing for non-MVC applications and non-controller beans to enable input validation for annotated beans?
Method level validation is not part of the Bean Validation specification (JSR 303). Method level validation is a suggestion in the spec added in appendix C.
Hibernate Validator 4.2 (a beta is out already) is implementing this suggestion and allows to place JSR 303 annotations on method parameters and return values. Of course you will still need some Spring glue code, but that should not be too hard.
Also Bean Validation 1.1 will add method level validation officially to the spec (not just as appendix/recommendation). See also http://beanvalidation.org/
Using MVC, this is enabled for #Controller annotated beans
#Valid is just a marker in Controller beans that hides the code that does the validation and puts all constraint violations in Errors in a nice way. Spring designers could have invented their own annotation to do the same thing.
The real use of #Valid annotation is in the class (bean) that you are validating with JSR 303 validator and its primary use is to validate the object graph. Meaning one bean can have other
bean references with #Valid annotation to trigger validation recursively.
Outside the MVC, you can use configured validator to validate any bean that uses JSR 303 annotations but, unlike the nicely populated Errors in controller, you will have to decide yourself what you are going to do with constraint violations.
So, to answer your question, there is no standard way. To have the same appearance as in a controller, you could use #Valid annotation (or create a new one) to run AOP advice to validate a bean and populate a 'ViolationCollector' (something like Errors in MVC) that must be passed to a method.
The answers seem to be quite old. As of now, you can utilize #Validated and MethodValidationPostProcessor for method inline validation of any Spring beans. They are basically responsible for creating pointcut-like behavior for Spring managed beans of any tier, not Controllers specifically.
Also see my other answer.

Categories

Resources