Hibernate验证注释 - 验证至少一个字段不为空

Res*_*h32 10 java validation annotations hibernate

有没有办法使用此处定义的注释定义Hibernate验证规则,说明至少有一个字段不为空?

这将是一个假设的例子(@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;

}
Run Code Online (Sandbox Code Playgroud)

在图示的情况下,fieldA可以为null或fieldB可以为null,但不能同时为两者.

一种方法是创建我自己的验证器,但我想避免它已经存在.如果你已经有一个验证器,请分享一个验证器...谢谢!

Res*_*h32 14

我终于写了整个验证器:

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;
                }
            }

        }

}
Run Code Online (Sandbox Code Playgroud)

用法示例:

@Entity
@CheckAtLeastOneNotNull(fieldNames={"fieldA","fieldB"})
public class Reward {

    @Id
    @GeneratedValue
    private Integer id;

    private Integer fieldA;
    private Integer fieldB;

    [...] // accessors, other fields, etc.
}
Run Code Online (Sandbox Code Playgroud)


Sla*_*hin 5

只需编写自己的验证器。不应该很简单:迭代字段名称并使用反射获取字段值。

概念:

Collection<String> values = Arrays.asList(
    BeanUtils.getProperty(obj, fieldA),
    BeanUtils.getProperty(obj, fieldB),
);

return CollectionUtils.exists(values, PredicateUtils.notNullPredicate());
Run Code Online (Sandbox Code Playgroud)

在那里我使用了commons-beanutils和 的方法commons-collections