2012-08-31 624 views
9

有没有一种方法可以使用注释定义一个Hibernate验证规则here,指出至少有一个字段不应为空?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; 

} 

在示出的情况下,可以FIELDA为空或fieldB可以为空,但不能同时使用。

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

回答

13

我终于写了整个验证:

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. 
} 
3

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

理念:

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

return CollectionUtils.exists(values, PredicateUtils.notNullPredicate()); 

这里我使用commons-beanutilscommons-collections方法。

+0

谢谢,帮我写使用PropertyUtils.getProperty内省的部分。 – Resh32

相关问题