Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate Validator : Using if - else kind of logic in annotation

I am using Hibernate validator like @NotEmpty to see if a specific property in a class is empty or not. The class is as as shown:

@Entity
@Table(name="emergency_messages")
public class EmergencyMessages implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id", nullable=false)
private Integer id;

@NotEmpty(message="Home message cannot be empty")
@Column(name="home_page_message")
private String homePageMessage;

@Range(min=0, max=1, message="Please select one of the display announcement value")
@Column(name="messages_enabled")
private Integer messagesEnabled;
}

So far so good. Whenever the property "homePageMessage" is empty I can see that the correct error message in the form in the browser.

Now the situation has changed. The new requirement is that the property "homePageMessage" can be empty only if the other property "messagesEnabled" is set to 1. If it is set to 0 then there should be no empty check done for "homePageMessage". In simple words the validation of "homePageMessage" should now be dependent on the "messagesEnabled" value.

My question: Is this possible to do with annotations? If not, then I will have to dismantle my hibernate validator mechanism and create my own validation class.

like image 837
Raj Avatar asked Sep 11 '12 18:09

Raj


3 Answers

I think you need to write custom annotation to achieve this. Also you can use other hibernate validation constraint with custom annotation, no need to remove anything.
Check this link for details.

like image 166
Ajinkya Avatar answered Oct 19 '22 03:10

Ajinkya


Following is the code that I came up with (after suggestions from Ajinkya and Alex):

Customized Annotation:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ElementType.TYPE})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Constraint(validatedBy=HomePageEmptyMessageValidator.class)
public @interface HomePageEmptyMessage {

String message() default "";

 Class<?>[] groups() default {};

 Class<? extends Payload>[] payload() default {};
}

Customized Validator:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class HomePageEmptyMessageValidator implements ConstraintValidator<HomePageEmptyMessage, EmergencyMessages> {

@Override
public void initialize(HomePageEmptyMessage homePageEmptyMessage) {
}

@Override
public boolean isValid(EmergencyMessages emergencyMessages, ConstraintValidatorContext context) {

    if (emergencyMessages == null) {
        return false;
    }

    Integer messageEnabled = emergencyMessages.getMessagesEnabled();
    if (messageEnabled != null) {
        if (messageEnabled == 1) {
            String homePageMessage =  emergencyMessages.getHomePageMessage();
            if (Util.isNullOrEmpty(homePageMessage)) {
                return false;
            } else {
                return true;
            }
        } else {
            return true;
        }
    }

    return false;
}

}

Usage of customized annotation in the code:

@Entity
@Table(name="emergency_messages")
@HomePageEmptyMessage(message="Home page annoucement cannot be empty if the Display  Announcement is set to Yes")
public class EmergencyMessages implements Serializable {

private static final long serialVersionUID = -7870767517772161300L; 

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id", nullable=false)
private Integer id; 

@Column(name="home_page_message")
private String homePageMessage;

@Range(min=0, max=1, message="Please select one of the display announcement value")
@Column(name="messages_enabled")
private Integer messagesEnabled;
}

I hope it helps someone.

like image 24
Raj Avatar answered Oct 19 '22 04:10

Raj


What you need is a ConstraintValidator implementation for your entity, using the @Constraint annotation on it.

This is where you will put conditions on fields that depends on other ones. Constraints using annotations on field are supposed to be used for check that can be made on the field itself, and not depending on another ones (like max size, nullable, etc...).

like image 1
Alex Avatar answered Oct 19 '22 03:10

Alex