In this post, we will see how we can create our own custom constraints tailored to our specific requirements.
Creating our own custom constraint is not that much complicated, it is a matter of defining two steps :
a) Create a constraint annotation
b) Create a constraint validation
I am going to explain step by step for creating our own constraint called @Required which is the combined of @NotNull and @NotEmpty.
Now let us start.
Environment
- Eclipse 3.7 Indigo IDE
- Hibernate 4.1.1
- JavaSE 1.6
- MySQL 5.1
Step 1:
Let us set up the environment first. Follow this post to set up Hibernate with java in eclipse IDE.
Step 2:
We need to add some more jar files for Validator. Please follow the steps
- Right click on Project and Select Properties.
- Select Java Build Path.
- Click “Add External JARs..” and include the following jar files. (you can also download by clicking the following files)
hibernate-validator-4.0.2.GA.jar
hibernate-validator-annotation-processor-4.1.0.Final.jar
slf4j-simple-1.4.2.jar
log4j-1.2.15.jar
slf4j-api-1.4.2.jar
validation-api-1.0.0.GA.jar
Step 3
In the mysql, create the following table.
CREATE TABLE `validatorexample5` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`firstName` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=INNODB DEFAULT CHARSET=latin1
Step 4
Now let us create the java bean without our constraint. Later we will come back , add our newly created custom constraint.
package domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import myConstraints.Required;
@Entity
@Table(name = "validatorexample5")
public class validatorexample5 {
@Id
@GeneratedValue
@Column(name = "ID")
private int ID;
@Column(name = "FirstName")
private String firstName;
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
Now let us map this class in the hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/sampledb</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Mapping Classes -->
<mapping class="domain.validatorexample5" />
</session-factory>
</hibernate-configuration>
Very Important, We need add one more property in the above xml file as follows
<property name="javax.persistence.validation.mode">none</property>
package domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import myConstraints.Required;
@Entity
@Table(name = "validatorexample5")
public class validatorexample5 {
@Id
@GeneratedValue
@Column(name = "ID")
private int ID;
@Column(name = "FirstName")
private String firstName;
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/sampledb</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Mapping Classes -->
<mapping class="domain.validatorexample5" />
</session-factory>
</hibernate-configuration>
package myConstraints;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = RequiredValidator.class)
@Documented
public @interface Required {
String message() default "{default message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
package myConstraints;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class RequiredValidator implements ConstraintValidator<Required, String> {
public void initialize(Required constraintAnnotation) {
}
public boolean isValid(String value, ConstraintValidatorContext constraintContext) {
if (value == null) {
return false;
}
if (value instanceof String) {
String stringValue = (String) value;
if (stringValue.trim().length() == 0) {
return false;
}
}
return true;
}
}
package domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import myConstraints.Required;
@Entity
@Table(name = "validatorexample5")
public class validatorexample5 {
@Id
@GeneratedValue
@Column(name = "ID")
private int ID;
@Column(name = "FirstName")
@Required(message="First name cannot be empty or null")
private String firstName;
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
package test;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.hibernate.Session;
import HibernateUtilities.HibernateUtil;
import domain.validatorexample5;
public class Test {
public static void main(String[] args) {
validatorexample5 v1 = new validatorexample5();
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<validatorexample5>> constraintViolations = validator
.validate(v1);
// printing the results
for (ConstraintViolation<validatorexample5> constraintViolation : constraintViolations) {
System.out.println(constraintViolation.getPropertyPath() + " -> "
+ constraintViolation.getMessage());
}
Session session = HibernateUtil.beginTransaction();
session.save(v1);
HibernateUtil.CommitTransaction();
}
}
2 [main] INFO org.hibernate.validator.util.Version - Hibernate Validator 4.0.2.GA
12 [main] INFO org.hibernate.validator.engine.resolver.DefaultTraversableResolver - Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
firstName -> First name cannot be empty or null
log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into validatorexample5 (FirstName) values (?)
That’s all