Hi I want to know how to restrict a field to accept particular values. Lets say if there a Bean
class Student{
#NotNull
private int id;
// Country should be either India or USA
private String Country;
}
Please let me know if you are aware of any annotation to be used for the country field. Thanks for your help.
Like afzalex said, use an enumeration to limit the choices. You can use a custom Bean Validation Constraint public #interface CountryConstraint to specify the allowed enumeration entries and then implement a constraint validator public class CountryValidator implements ConstraintValidator<CountryConstraint, Country> to validate the values. Here and here is a completes example on how to achieve this.
Related
I'm looking to implement bean validation with groups based on parameter. The idea is to have methods with signature like:
#POST
#Path("/id-{id}")
public SomeDTO updateProducer(#PathParam("id") String id, #MatrixParam("update") Class<ConvertGroupTarget> update, #Valid SomeDTO data);
This would serve as an equivalent of explicit ConvertGroup declaration, such as:
#POST
#Path("/id-{id}")
public SomeDTO updateProducer(#PathParam("id") String id, #Valid #ConvertGroup(from=Default.class, to=/*some class that implements ConvertGroupTarget*/) SomeDTO data);
Is this even possible at all? We're using Jersey with hibernate-validator.
EDIT: the purpose of this all. Say I want to validate beans based on some validation group for specific purposes. For example, some bean can have different rules that apply to creating and updating it. So the bean declaration looks like this:
class SomeDTO {
#NotNull(groups = {Create.class, Update.class})
private String id;
#NotNull(groups = {Create.class, Update.class})
private String name;
#NotNull(groups = Update.class)
private String something;
//getters, setters etc.
}
The classes Create and Update are just some marker classes/interfaces to provide typed declaration of the groups.
Now, say the API user is creating an entity and he does
POST /id-X123/;update=create. Here I just want to validate the ID and the name, but don't really care about the something property of the bean. But when API user wants to update the bean, the API should require that he specifies even the something property. This is normally done by converting the validation group - #ConvertGroup(from = Default.class, to = Create.class) for creating and #CovertGroup(from = Default.class, to = Update.class) for updating. However, I'm looking to skip the explicit declaration of a ConvertGroup annotation and do this programatically based on parameter.
ConvertGroup defines static group conversions so you won't have the ability to parameterize them. You define them once and for all.
I think what you want to do is to call the Validator with a group. I don't use Jersey so I don't know if they have a hook for it but what you should look for is this:
Set<ConstraintViolation<SomeDTO>> violations =
validator.validate(someDTO); // validate the default group
Set<ConstraintViolation<SomeDTO>> violations =
validator.validate(someDTO, Update.class); // validate the Update group
Problem:
How to save object Account as nested object when only ID is needed without getting ConstraintValidator exception?
Problem is because i have set validation rules to class, but when i want to save sem entity as nested object i get exception that some property values are missing. So i would liek to have different validation rules when i want to persist object as a whole and when i want to use it only sa nested object (when only ID is needed).
public class Account {
private int id;
#NotNull
private String name;
#NotNull
private String lastName;
#NotNull
private String userName;
//getters&setters
If I include Account as nested object i just need ID to be able to use it as FK (account entity is already in DB), but because of #NotNull annotation i get Exception.
Is there a way to ignore those annotations from Account when trying to save object Shop or how to create different validation rules for Account to validate just soem other properties and not all?
public class Shop {
private int id;
private Account owner; // only ID is needed
Do you have any basic example? I dont understand those in documentation. I have already read documentation before posting here.
You want to look at Bean Validation groups where you can classify specific validations so they are only activated when that group is validated and ignored otherwise.
You can refer to the documentation here for details.
Taking an example from the documentation:
// This is just a stub interface used for tagging validation criteria
public interface DriverChecks {
}
// The model
public class Driver {
#Min(value = 18, message = "You must be 18", groups = DriverChecks.class)
private int age;
// other stuffs
}
A group is nothing more than a tag that allows you to enable/disable validations based on specific use cases at run-time. By not specifying the groups attribute on a bean validation annotation, it defaults to the Default group, which is what Bean Validation uses if a group-tag isn't specified at the time of validation.
That means the following holds true:
// Age won't be validated since we didn't specify DriverChecks.class
validator.validate( driver );
// Age will be validated here because we specify DriverChecks.class
validator.validate( driver, DriverChecks.class );
This works great when you're triggering the validation yourself inside your service methods because you can manually control which group checks are applicable based on that method's use case.
When it comes to integrating directly with Hibernate ORM's event listeners that can also trigger bean validation, group specifications become a bit harder as they must be specified based on the event-type raised by hibernate.
javax.persistence.validation.group.pre-persist
javax.persistence.validation.group.pre-update
javax.persistence.validation.group.pre-remove
For each of the above properties you can specify in the JPA properties supplied to Hibernate, you can list a comma delimited list of groups that are to be validated for each of those event types. This allows you to have varying checks during insert versus update versus removal.
If that isn't sufficient, there is always the fact that you can create your own constraint validator implementation and annotation to plug into Bean Validation and specify that at the class or property level.
I have often found this useful in cases where values from multiple fields must be validated as a cohesive unit to imply their validity as the normal field-by-field validations didn't suffice.
We have a requirement that every fields of the object must be validated in a special order.
For example, we have Person object like below:
public class Person {
#NotNull
private String firstName;
#NotNull
private String lastName;
// getter and setter
}
When I use the javax.validation.Validator to validate this object, we need to make sure that the firstName always be validated first and then lastName. Is there any way for hibernate validator archive that requirement?
You want to use group sequences. In particular you probably want to redefine the default group for your entity. See also Redefining the Default group for a class as defined by the Bean Validation specification .
Does JPA with Spring-Data have a problem with attributes with underscores "_" in their names? This is my interface that extends JpaRepository:
public interface I_My_Class extends JpaRepository<MyClass, Long> {
public MyClass findByA_my_table_id (Long headerId);
}
This line: findByA_my_table_id (Long headerId); gives this error:
Invalid derived query! No property "a" found for type MyClass !
If I name the method public MyClass findBya_my_table_id (Long headerId); it gives me the same error. If I name the attribute amytableid without the underscores I don't get the error but if I do that it's not easy to read later on. This is the class where I have the table attribute:
#Entity
#Table(name="MyTable")
public class MyClass implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column (name="MY_TABLE_ID", nullable=false)
private Long a_my_table_id; // <-- this is the attribute that I try to put in the named query
}
Yes Spring Data will have problem with underscores in Entity attribute names. Reason being JpaRepository simply expects attributes with proper Java Standard naming conventions eg property names should be in lower case. (if you can add multiple nouns to make it more meaning full then better make first letter of nouns in upper case except the first one)
String aMyTableId;
Above property would create tell JpaRepository to create a method like
List<MyClass> findByAMyTableId(String aMyTableId);
This would not give compilation error.
In case you want to write custom queries then you can use #Query API. Here you can write Object oriented query.
#Query("Select myclass from MyClass myclass where myclass.aMyTableId=?1 and myclass.activeFlag='1'")
List<MyClass> findByAMyTableIdWithActiveFlagOn(String aMyTableId);
You can find many tutorials and sites explaining how to write custom queries.
Right now I have a class BaseSchedule It is used by 4 classes (composition). I would like to validate in two use classes and not in the others. I am a little stumped on how to do so.
My BaseSchedule looks like the following:
#Embeddable
#DatesStartBeforeEnd(start = "startDateTime", end = "endDateTime")
public class BaseSchedule implements Serializable {
private Date startDateTime;
private Date endDateTime;
}
I would like to check to make sure that the startDateTime and endDateTime are not null when I go to persist the data to my database. Normally I would provide a #NotNull to each of the fields.
public class TimeSlot implements Scheduleable {
#Embedded
private BaseSchedule schedule;
}
But... in the case of my TimeSlotTemplate I do not want validation as I know it will be null.
public class TimeSlotTemplate extends SchedulableClassTemplateEvent {
#Embedded
private BaseSchedule schedule;
}
If you're using Hibernate Validator as your BV provider, one solution might be to use a custom default group sequence provider.
For this to work, your BaseSchedule object would have to know about the "role" it currently has, e.g. by passing an enum with values such as SlotSchedule, TemplateSchedule etc. to its constructor. Depending on the role a group sequence provider could then determine the sequence to validate and return a sequence which does not contain the #NotNull constraints if the role is TemplateSchedule.
Not that this approach requires that you use the default sequence during JPA lifecycle validation.
I think this could be done using the #PrePersist Annotation.
#PrePersist
public void prePersist(){
if(isPerformNullableCheck()){
// check for null values and raise an error if invalid
}
}
in your TimeSlotTemplate, you can set the performNullableCheck property to false...
Another way might be to add a class into the hierarchy.
BaseSchedule contains the properties needed and e.g. ValidatedSchedule (extends BaseSchedule) overrides those and performs the notnull checks. Don't know whether this works or not. Also this would probably not be the best solution for your problem..?