Play framework, Different constraints for different requests - java

How to implement different constraints for different requests? For example, there is User class:
public class User extends Model{
#Required
#Email
#Id
public String email;
#Required
#Column(length = 50)
public String firstname;
#Required
#Column(length = 50)
public String lastname;
#Required
public String password;
}
When I create a new user, all constraints are required. But when I update user information, I don't need the password constraint.
Should I create separate classes for createUser() and updateUser() actions?
Is there any way I can use just one class?

It is bad practise to mix "back-end entity" annotations with "front-end entity" annotations. Create separate class for inserting user and updating user with #Required annotations accordingly. Remove front-end annotations from User entity and leave only JPA annotations like #Id #Column etc.

As Play's validation framework conforms to the Java bean validation specification (JSR-303), you can use the validation groups feature that is part of the spec. This is exactly what you are looking for - a neat way of enforcing different validation rules for different actions. You can see an example of how to use it in code in this answer I gave to a similar question.

Related

Should I use different DTO for Create and Update?

I have create and update operation for user and the following UserDto
public class UserDto {
#NotBlank
private String username;
#NotBlank
private String password;
#NotBlank
private String mobileNo;
... other variables, etc.
}
For update operation, I don't want to update the password, I only want to update other variables. Then the password would be received as null (hence not passing #NotBlank).
But the #NotBlank is required for create operation. What is the best approach to solve this?
Should I create 2 Dtos e.g. UserCreateDto, UserUpdateDto (without password field).
I'm not sure if this is a good practice.
Assuming you will have different APIs for create and update operation. You can use same dto and for password field you can put validation at backend side based on operation rather than in DTO itself.

How to hardcode group information on field for cascading validation

I have the following bean;
public class Customer {
#NotNull(groups = New.class)
private String id;
#Valid
private List<CustomerDetail> detailList;
}
As you see, I cascade validation down to each CustomerDetail in detailList by annotating the field with #Valid, but I wish to propagate the validation with a hard-coded group, is that possible? Whatever group is supplied for validation, I wish a fixed group, namely New to be active in validation of detailList.
This is due to my conflicting requirements, one wishes to treat details as a sub-resource of Customer therefore I need full validation on it all the time when it is validated within a customer pojo. Another requirement is to treat each detail as a separate resource, therefore I need to do patch for some fields, so when it is validated separately, different groups can be applied.
public class CustomerDetail {
#NotNull(groups = New.class)
private String desc;
private String remark;
}
So when it is any sort of operation for Customer, every CustomerDetail in customerList should use New group, even if Customer does not necessarily use that group for validation.
In a way, I want to do this;
public class Customer {
#NotNull(groups = New.class)
private String id;
#Validated(New.class)
private List<CustomerDetail> detailList;
}
But I was unable to find such a feature, I wanted to do this to evade creating multiple groups, which was deemed confusing.
You need to introduce your own annotation to have class level constraints. Create a custom annotation with own validation logic implemented in the validator.
See the chapter 6.2. Class-level constraints of the doc
Or see the example

How to impose common constraint on class with javax.validation library?

I am using Bean Validation constraints to validate class instances at run time. I have many DTOs where each has multiple fields often with a common constraint. I want to add a constraint to the class so that it applies to all the properties of the class. (As lombok #NotNull constraint).
e.g
class Person {
#NotNull
private String name;
#NotNull
private String address;
#NotNULL
private String contact;
}
I want to make it something like this.
#NotNull
class Person {
private String name;
private String address;
private String contact
}
You cannot do this with plain Bean Validation. So just adding #NotNull to the class won't work.
One potential approach could be to utilize XML configuration. The idea would be to have your own annotation MyNotNull. Your framework would need to scan for these annotations and build the programmatic configuration for the class in question. This could for example be done via a annotation processor during compile time. Once you have the constraint mapping XML files add them to your jar and reference them in validation.xml. That's just a basic idea. Personally, I am not sure whether it is worth the effort.

Spring Hibernate Bean Validation #valid

I know it is not new question in this forum but I am very confused what should i do.
Problem: I am developing one application with spring mvc + hibernate. For server side validation I am using #valid annotation in controller and #null and #notNull annotation in my bean.
e.g
public class User implements Serializable {
private static final long serialVersionUID = 2158419746939747203L;
#Id
#Column(name="USER_ID")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long userId;
#Column(name="USERNAME", unique = true)
#NotEmpty #NotNull #Size(min=6, max=20)
private String username;
#Column(name="PASSWORD")
#NotEmpty #NotNull #Size(min=6, max=20)
private String password;
This validation is happening fine and data is also saving in DB.
But I want to validate unique constraint,referential integrity and other constraint using annotation without any validator class.
Is it possible? if no, then what is best and easiest way to to do it(less coding)? I will appreciate if framework will do it for me.
Saurabh,
For unique constraint in table,
#Id
You will be able to enforce referential integrity via hibernate annotations as well
eg.
#OneToOne(mappedBy = "foo")
Here is an example post
Referential integrity with One to One using hibernate
Here is a very detailed tutorial also exploring the same:
http://www.journaldev.com/2882/hibernate-tutorial-for-beginners-using-xml-annotations-and-property-configurations
You could write a "CustomUniqueConstraintValidator" kinda like mentioned in
http://www.journaldev.com/2668/spring-mvc-form-validation-example-using-annotation-and-custom-validator-implementation
You can also pass in paramters from the annotation to the custom validator.
eg.
#CustomValidDate("columnName")
To make a generic class that applies for any field /column
1. YOu can write a generic custom validator
2. use annotaiton parameters (on each class attribute) to pass in the table name and column name.
3. Then in the validator you can use the table name, column name to apply your validation logic (unique etc).
Thanks,
Paul

Patterns for Data validation when using a DAO

I am developing a web application and am trying to determine the best practice for validating data before it is persisted.
I currently have 2 DAO interfaces:
UserDAOInt - defines what operations a user can perform, throws data validation exceptions
UserDAOPersistenceInt - defines what operations a user can perform, throws jpa exceptions
I have corresponding implementations for the DAO Interfaces:
UserDAOImpl - implements UserDAOInt, validates the data by making sure all data required is present, making sure that the entities being updated or deleted exist in the database. If there is an issue, an exception is thrown. If everything is ok, a call is made to the corresponding method in the classes UserDAOPersistenceInt implementation.
UserDAOPersistenceImpl - implements the UserDAOPersistenceInt. The only validation that occurs is checking for null objects returned by EntityManager calls, just in case they were removed between the time the validation occurred and the call to the method. Throws persistence related exceptions or Exception if a null object was returned by the EntityManager.
When the data comes in from the servlets, I validate the data on the web tier side before even attempting to use a DAO.
My question is, is it bad practice to validate the data on both the web tier side, and again within the DAO's?
I'm asking because I'm finding that I'm maintaining 2 sets of validations.
The validation that takes place on the servlet is the validation of the data coming in from the user, mainly in forms. If a validation error happens here, I generally use the text of the validation error as feedback that is presented to the user, for example, First Name is required, when filling out a form.
Once I make it to the DAO, I'm expecting for the operation to complete successfully, because I have 'vetted' the data within the web tier. Any exceptions that occur in the validation at the DAO level I use as the text that is logged, and then send a 500 error response, for example, but the underlying message in the exception is not something that I display to the user.
I would really like to only have 1 place where validations are maintained so that I don't have to make changes in 2 places, but I'm really just looking to find out what the established best practices are.
I would hand this over to the bean validation framework. It allows you to manage the validation rules in a single place, as annotations to the bean, like this:
#Entity
public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
protected String firstName;
#NotNull
protected String lastName;
#Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\."
+"[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#"
+"(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
message="{invalid.email}")
protected String email;
#Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$",
message="{invalid.phonenumber}")
protected String mobilePhone;
#Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$",
message="{invalid.phonenumber}")
protected String homePhone;
#Temporal(javax.persistence.TemporalType.DATE)
#Past
protected Date birthday;
}
Validation will then be performed automatically during the JPA lifecycle events (PrePersist, PreUpdate, and PreRemove).
Manual validation can be done like this:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Contact>> errors = validator.validate(bean);
See the JPA Entity tutorial and the Bean validation tutorial for more information on what's possible.

Categories