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.
Related
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.
I want to combine Hibernate and Spring Validators. I came across this link:
http://www.mkyong.com/spring-mvc/combine-spring-validator-and-hibernate-validator/
And it is working as expected. However to get it to work have to comment out InitBinder, enter the method and throw an exception within method itself if there are errors in the BindingResult.
I would prefer for it to be like #Validated where it throws the exception prior to even entering the method
#Validated is for Spring and throws MethodArgumentNotValidException if any errors come up.
Is there a way to use invoke Hibernate validate as part of Spring Validator class or call both and bind them to the same Result
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/validation/beanvalidation/SpringValidatorAdapter.html
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.html
Came across the above classes: Adapter that takes a JSR-303 javax.validator.Validator and exposes it as a Spring Validator while also exposing the original JSR-303 Validator interface itself.
This solved the issue. I created a SpringValidatorAdapter bean and am injected it into my Spring Validators and calling validate on the object
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.
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.
I'm looking into using JSR-303 with hibernate validator. We would like to be able to have different validations per each customer or have a base set of constraints and allow them to be overridden.
I'm not sure what's the best way to do this.
Using annotations for constraints is not suitable since they're essentially hard-coded in the models. I know I can use XML to externalize the validations (creating META-INF/validation.xml which specifies constraint-mapping files). But I'm not really sure how to easily make this configurable for multiple customers.
I suppose I would like to be able to set a simple property so that when we deploy it uses a completely different set of constraint-mapping files.
Any ideas?
You could create a ValidatorFactory per customer which you configure with customer-specific constraint mapping XML files like this:
ValidatorFactory validatorFactory = Validation
.byDefaultProvider()
.configure()
.addMapping(...) //input stream with an XML constraint mapping
.addMapping(...) //another input stream with an XML constraint mapping
.buildValidatorFactory();
When you're working with Hibernate Validator, you could also use the API for programmatic constraint declaration to create individually configured validator factories.