Spring - mixing annotation and validator-based validations - java

I've following problem, there's a regular spring model (let's call it "A") with some validations-related annotations. Next, there's a command object (regular POJO class that defines some field, one of them is object of type A). The command object implements Validator interface, to make binding and validation work in controller methods.
Question is, how to make use of annotations-configured validations inside the command object (given it implements Validator interface, hence it has supports() and validate() methods).
What I'm trying to achive is to have basic validations on model that is reused and mixed with some heavier business-logic validations in other parts of the system.

I have had the exact same problem. I wanted to use automatic annotation validation for "simple things" and then pass the complex validation logic to my custom spring Validator. But whenever I set the controller validator, all of hibernate's validation stopped working, as described at the end of this tutorial:
http://www.captaindebug.com/2011/07/applying-custom-spring-validator-to.html#.VQR0OI7F-gd
This technique should be used when you need to do ALL your
controller’s validation yourself, and you can’t or don’t want to make
use of the Hibernate’s reference implementation of a JSR 303
validator. From this, you’ll guess that you can’t mix your own custom
Spring validator with Hibernate’s JSR 303 validator. For example,
adding the built-in annotations to the Address command object will
have no effect:
You should forget about old style Spring Validator and delete "setInitBinder()" as described in this related question:
Spring MVC validator annotation + custom validation
You should then only rely on hibernate validation and JSR303.
To add a complex validation to your class (model), say you want to check two date fields - use a custom annotation constraint on class level as described in the link below.
https://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/validator-customconstraints.html#section-class-level-constraints
Hope this helps.
Best Regards,
Alexander

Once look at this may this help you
Using both JSR-303 and Traditional Bean Validation?. There i have given one example for custom validation for model using custom annotation.

Related

How does spring instantiate a bean from a annotated interface (e.g. JpaRepository)? [duplicate]

I have been working with Spring Data JPA repository in my project for some time and I know the below points:
In the repository interfaces, we can add the methods like findByCustomerNameAndPhone() (assuming customerName and phone are fields in the domain object).
Then, Spring provides the implementation by implementing the above repository interface methods at runtime (during the application run).
I am interested on how this has been coded and I have looked at the Spring JPA source code & APIs, but I could not find answers to the questions below:
How is the repository implementation class generated at runtime & methods being implemented and injected?
Does Spring Data JPA use CGlib or any bytecode manipulation libraries to implement the methods and inject dynamically?
Could you please help with the above queries and also provide any supported documentation ?
First of all, there's no code generation going on, which means: no CGLib, no byte-code generation at all. The fundamental approach is that a JDK proxy instance is created programmatically using Spring's ProxyFactory API to back the interface and a MethodInterceptor intercepts all calls to the instance and routes the method into the appropriate places:
If the repository has been initialized with a custom implementation part (see that part of the reference documentation for details), and the method invoked is implemented in that class, the call is routed there.
If the method is a query method (see DefaultRepositoryInformation for how that is determined), the store specific query execution mechanism kicks in and executes the query determined to be executed for that method at startup. For that a resolution mechanism is in place that tries to identify explicitly declared queries in various places (using #Query on the method, JPA named queries) eventually falling back to query derivation from the method name. For the query mechanism detection, see JpaQueryLookupStrategy. The parsing logic for the query derivation can be found in PartTree. The store specific translation into an actual query can be seen e.g. in JpaQueryCreator.
If none of the above apply the method executed has to be one implemented by a store-specific repository base class (SimpleJpaRepository in case of JPA) and the call is routed into an instance of that.
The method interceptor implementing that routing logic is QueryExecutorMethodInterceptor, the high level routing logic can be found here.
The creation of those proxies is encapsulated into a standard Java based Factory pattern implementation. The high-level proxy creation can be found in RepositoryFactorySupport. The store-specific implementations then add the necessary infrastructure components so that for JPA you can go ahead and just write code like this:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
The reason I mention that explicitly is that it should become clear that, in its core, nothing of that code requires a Spring container to run in the first place. It needs Spring as a library on the classpath (because we prefer to not reinvent the wheel), but is container agnostic in general.
To ease the integration with DI containers we've of course then built integration with Spring Java configuration, an XML namespace, but also a CDI extension, so that Spring Data can be used in plain CDI scenarios.

How are Spring Data repositories actually implemented?

I have been working with Spring Data JPA repository in my project for some time and I know the below points:
In the repository interfaces, we can add the methods like findByCustomerNameAndPhone() (assuming customerName and phone are fields in the domain object).
Then, Spring provides the implementation by implementing the above repository interface methods at runtime (during the application run).
I am interested on how this has been coded and I have looked at the Spring JPA source code & APIs, but I could not find answers to the questions below:
How is the repository implementation class generated at runtime & methods being implemented and injected?
Does Spring Data JPA use CGlib or any bytecode manipulation libraries to implement the methods and inject dynamically?
Could you please help with the above queries and also provide any supported documentation ?
First of all, there's no code generation going on, which means: no CGLib, no byte-code generation at all. The fundamental approach is that a JDK proxy instance is created programmatically using Spring's ProxyFactory API to back the interface and a MethodInterceptor intercepts all calls to the instance and routes the method into the appropriate places:
If the repository has been initialized with a custom implementation part (see that part of the reference documentation for details), and the method invoked is implemented in that class, the call is routed there.
If the method is a query method (see DefaultRepositoryInformation for how that is determined), the store specific query execution mechanism kicks in and executes the query determined to be executed for that method at startup. For that a resolution mechanism is in place that tries to identify explicitly declared queries in various places (using #Query on the method, JPA named queries) eventually falling back to query derivation from the method name. For the query mechanism detection, see JpaQueryLookupStrategy. The parsing logic for the query derivation can be found in PartTree. The store specific translation into an actual query can be seen e.g. in JpaQueryCreator.
If none of the above apply the method executed has to be one implemented by a store-specific repository base class (SimpleJpaRepository in case of JPA) and the call is routed into an instance of that.
The method interceptor implementing that routing logic is QueryExecutorMethodInterceptor, the high level routing logic can be found here.
The creation of those proxies is encapsulated into a standard Java based Factory pattern implementation. The high-level proxy creation can be found in RepositoryFactorySupport. The store-specific implementations then add the necessary infrastructure components so that for JPA you can go ahead and just write code like this:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
The reason I mention that explicitly is that it should become clear that, in its core, nothing of that code requires a Spring container to run in the first place. It needs Spring as a library on the classpath (because we prefer to not reinvent the wheel), but is container agnostic in general.
To ease the integration with DI containers we've of course then built integration with Spring Java configuration, an XML namespace, but also a CDI extension, so that Spring Data can be used in plain CDI scenarios.

Java Bean Validation: Posible to specify runtime validations?

I am maintaining a web app that is using Java bean validations (as part of JSR303 I believe).
Members are mapped with annotations like #Pattern and then we have a LocalValidatorFactoryBean that performs the validation. The Validator that this factory bean bootstraps is actually the Hibernate validation instance.
My problem is that my #Pattern regex needs to be loaded at runtime when my application starts up, so I cannot use the annotation.
Therefore, I'm wondering if there is an alternative way such as XML to plug in such validation?
If not, I may just have to use a separate Spring validator to do this work
I recommend creating custom validator as described in http://docs.spring.io/spring/docs/3.0.0.RC3/reference/html/ch05s07.html#validation.beanvalidation.spring.constraints. Thus you will need to check the value agains the pattern in the code of constraint validator class.
You can configure bean validation using XML for such a thing. The syntax is a lot like the JavaBean XML format and maps rather well to the hierarchical structure of the equivalent Java syntax.

Writing a custom Spring #Cacheable annotation

I'm currently writing a custom #Cacheable annotation that will take additonal meta-data attributes in addition to those that Spring's #Cacheable provides. However, Spring would need to know how to parse this new annotation. My understanding is that I'd need to extend and override AnnotationCacheOperationSource's determineCacheOperations() so that the new annotation can be parsed with an appropriate CacheableOperation class initialized from it. Is this the correct way to proceed?
Regards,
Steve
Depends.
As per AnnotationCacheOperationSource javadoc,
This class reads Spring's Cacheable, CachePut and CacheEvict
annotations and exposes corresponding caching operation definition to
Spring's cache infrastructure. This class may also serve as base class
for a custom CacheOperationSource.
So if you're asking for yes/no answer if you can extend that class for an extended behaviour of CacheOperationSource, the answer is yes.
However, what determineCacheOperations() method does is that it uses all the available CacheAnnotationParsers. The only default CacheAnnotationParser is SpringCacheAnnotationParser. If you have a custom one, just have another class implementing CacheAnnotationParser for your annotation. Spring should then use it automatically. You can take a look at the SpringCacheAnnotationParser source code to see how they do it.
Edit: ok, I was wrong in that this would happen automatically. My next suggestion is to
implement the interface CacheAnnotationParser, like you apparently already did
extend AnnotationCacheOperationSource so that you put your own CacheAnnotationParser in addition to Spring one in the internal parsers collection
define your custom AnnotationCacheOperationSource to use the same id as Spring one does, so it will override Spring internal. If id matches, it should override Spring one cleanly. This would be something like:
<bean id="annotationCacheOperationSource"
class="com.company.YourCustomAnnotationCacheOperationSource" />

Autowiring Validation without Naming Controllers After Models in Spring

Very new to spring and working my way through validation.
I have examples working where I actually implement the spring Validator class, but am working on getting examples working without implementing the Validator class and instead using annotations directly on model class attributes such as #NotBlank and #Email.
My question is this. Is there anyway to make the above scenario (annotations directly on class attributes) work where you are not naming your Controllers after the models that they are implementing?
For example if I had a FormController class and one of the functions inside dealt with adding a user. Is there anyway to Autowire the validation for the User class directly to the Annotations on the the User class or am I stuck writing a UserValidator class and using that.
Have a look at Spring-Roo. I believe they do what you are asking for.

Categories