有没有一种方法可以使用此处定义的注释来定义Hibernate验证规则,说明至少一个字段不能为null?
这将是一个假设的示例(@OneFieldMustBeNotNullConstraint实际上不存在):
@OneFieldMustBeNotNullConstraint
@Entity @OneFieldMustBeNotNullConstraint(list={fieldA,fieldB}) public class Card { @Id @GeneratedValue private Integer card_id; @Column(nullable = true) private Long fieldA; @Column(nullable = true) private Long fieldB; }
在所示的情况下,fieldA可以为null或fieldB可以为null,但不能同时为两者。
一种方法是创建自己的验证器,但是我想避免它已经存在。如果您已经验证过,请分享一个验证人…谢谢!
我终于写了整个验证器:
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import javax.validation.Payload; import org.apache.commons.beanutils.PropertyUtils; @Target( { TYPE }) @Retention(RUNTIME) @Constraint(validatedBy = CheckAtLeastOneNotNull.CheckAtLeastOneNotNullValidator.class) @Documented public @interface CheckAtLeastOneNotNull { String message() default "{com.xxx.constraints.checkatleastnotnull}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; String[] fieldNames(); public static class CheckAtLeastOneNotNullValidator implements ConstraintValidator<CheckAtLeastOneNotNull, Object> { private String[] fieldNames; public void initialize(CheckAtLeastOneNotNull constraintAnnotation) { this.fieldNames = constraintAnnotation.fieldNames(); } public boolean isValid(Object object, ConstraintValidatorContext constraintContext) { if (object == null) return true; try { for (String fieldName:fieldNames){ Object property = PropertyUtils.getProperty(object, fieldName); if (property!=null) return true; } return false; } catch (Exception e) { System.printStackTrace(e); return false; } } } }
用法示例:
@Entity @CheckAtLeastOneNotNull(fieldNames={"fieldA","fieldB"}) public class Reward { @Id @GeneratedValue private Integer id; private Integer fieldA; private Integer fieldB; [...] // accessors, other fields, etc. }