2012-08-31 8 views
9

少なくとも1つのフィールドがヌルでないことを示す、hereというアノテーションを使用してHibernate検証ルールを定義する方法はありますか?これは、仮想的な例(@OneFieldMustBeNotNullConstraintが本当に存在していない)であろうHibernateの検証アノテーション - 少なくとも1つのフィールドがヌルでないことを確認する

:例示場合

@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であることはできませんがnullまたはFIELDBことができます。

自分のバリデータを作成する方法もありますが、すでに存在する場合は避けたいと思います。既に作成している場合は、1つのバリデータを共有してください...ありがとう!

答えて

13

は、私は最終的に全体のバリデータを書きました。
3

独自のバリデータを書きます。単純ではありません。フィールド名を繰り返し処理し、リフレクションを使用してフィールド値を取得します。

コンセプト:あり

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

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

私はcommons-beanutilscommons-collectionsからメソッドを使用していました。使い方の

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. 
} 
+0

おかげで、私はPropertyUtils.getPropertyを使ってイントロスペクションの一部を書く助け – Resh32

関連する問題