How to implement custom class level Constraint Validation without Annotation? - java

I use the javax.validation and have a Hibernate validator on a classpath.
I would like to validate entities of a specific class on the class level (not fields level).
I can do this with by creating a custom class-level annotation and a paired ConstraintValidator as shown below:
#Constraint(validatedBy = CustomValidator.class)
#Target({ ElementType.TYPE })
public #interface CustomConstraintAnnotation {
}
class CustomValidator
implements ConstraintValidator<CustomConstraintAnnotation, Object> {
}
However, I would like to avoid creating a custom annotation and assign a custom validator per entity type, so that the validator would be registered for this type and validate instances of this type by default when validator.validate(entity) is invoked without having to annotate the type.
The javax.validation.ConstraintValidator does not fit, because it works only in pair with an annotation.
Basically, I would like to create a mapping between the type and the corresponding custom validator without using an annotation.
Is there a way to achieve this?

Related

Create an entity class without #Entity annotation

Is it possible to create an entity without #Entity annotation.
I have an employee class which is not annotated with #Entity.
Question:
How entity class is identified by JPA?
Is it possible to use custom annotation let say #MyOwnEntity instead of #Entity?
Is there is a way I can override JPA method to indicate package(com.mt.own.example) type are containing entity class? Note: I am going to annotate all the class within (com.mt.own.example) package with my own annotation.
i dont know why would you do that but yes you can ...
#Documented
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface MyOwnEntity {
String name() default "";
}

Java validation of object with annotation directly

The conventional way of java validation is to define a class with properties and annotated with one or many validation constraint annotations such as #NotNull or #Future.
Is it possible to validate an object directly with validator constraint annotation without specifying a class. For example:
String a = "";
validator.validate(a, javax.validation.constraints.NotNull.class);
That's clearly not a use case for which Hibernate Validator has been designed.
What you would have to do is to create a ConstraintValidator from the constraint and the type of the object and then use the isValid() method. The entry point would be ConstraintValidatorManager.
It's an internal class so it's subject to change without warning, even in a micro version so I wouldn't recommend using it.

JSR303 Hibernate dynamic validator

I'm new to hibernate validator
I would like to have one annotation and many implementations. Problem is, that annotation should be placed in domain (api) module and implementations in corresponding implementation modules (xx-command, xx-query). So the parameter validatedBy of #Constraint annotation has to be empty.
Can I somehow dynamically tell to hibernate to use all implementations of specified annotation which can pass type which I need. Also I would like to have implementations in more than one submodule.
#Target({FIELD, PARAMETER})
#Retention(RUNTIME)
#Documented
#Constraint(validatedBy = {})
public #interface CanNotExists {
String message() default "com.foo.api.domain.validation.annotation.CanNotExists.message";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
this is my project structure (in dependency order accessor-command depends on accessor-query, accessor-query dependes on infrastrucutre ...)
-api
-infrastructure
-accessor-query
-accessor-command
I found this question and wanted to use xml configuration (see the edit section in answer), but it's not helpful because I would like to use implementation in many modules >>> as mentioned here
A given entity can only be configured once across all configuration files. The same applies for constraint definitions for a given constraint annotation. It can only occur in one mapping file. If these rules are violated a ValidationException is thrown.
So I can't split constraints to multiple xml configurations.
Basic need of this validator is to look into repository and validate if specified object already exists. I'm also using spring in my project so if somebody have better approach how to do this (even with spring or another framework), it will be welcome.
Thanks
Your question is tagged with 'spring', so may be you can use springs validation that under the hood uses hibernate :
[spring validation][1]
Let your validator implement the interface spring Validator, create a bean of it, thats it.

Is there a way to add a global annotation for all domains?

I want the annotation below to be the default for all of my domain objects.
#JsonInclude(Include.NON_NULL)
Rather than adding this manually to every domain class, I was wondering if there is a way to make this the default for all domains.
I am working with spring-boot application that utilizes Gradle for builds and JPA and Hibernate for persistence.
Java supports way to inherit annotation of super type if the annotation applied to super type is annotated with a meta annotation #Inherited doc.
But since the #JsonInclude annotation is not annotated with #Inherited, I think you'll have to add it manually to your domain classes.
You can make one SuperClass annotate the same with #JsonInclude(Include.NON_NULL) and extend it, like below:
#JsonInclude(Include.NON_NULL)
public class SuperClass {
}
public class SubClass extends SuperClass{
}

Make Java annotation act differently depending on field annotated

In Java, is there a way to change the behaviour of an annotation depending on the type of the annotated field?
I know that annotation presence is supposed to be tested by code. Not the opposite. But the case is rather particular: this is a Jackson 2.0 « inside » annotation which gather a list of annotations. We use it to define the field name (#JsonProperty) and the field serializing policies (#JsonSerialize).
The serialisation policies must be adapted to the annotated field. And, because we are talking of a framework, one unique annotation is far better than two separate ones.
#Retention(RUNTIME)
#JacksonAnnotationsInside.
#JsonProperty("_id")
#JsonSerialize(using=IdSerializer.class)
#JsonDeserialize(using=IdDeserializer.class)
public #interface Id {}
Some cases need to turn the serializers down, that's the point. In the following example, the String must be processed by the de/serializers, ObjectId don't. Both need to be renamed _id by the #JsonProperty.
public class Car {
#Id String id
}
public class Bus {
#Id ObjectId id
}
Any clues?

Categories

Resources