14

ここで定義されているように、少なくとも1つのフィールドがnullであってはならないことを示す注釈を使用して、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をnullにすることも、fieldBをnullにすることもできますが、両方を指定することはできません。

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

4

3 に答える 3

17

私はついにバリデータ全体を書きました:

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) {
                 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.
}
于 2012-08-31T10:09:07.573 に答える
5

独自のバリデータを作成するだけです。フィールド名を反復処理し、リフレクションを使用してフィールド値を取得します。

概念:

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

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

commons-beanutilsそこで、と のメソッドを使用しcommons-collectionsました。

于 2012-08-31T09:03:23.217 に答える