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.
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.
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.
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...).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With