2012-08-31 9 views
9

Czy istnieje sposób zdefiniowania reguły sprawdzania poprawności hibernacji przy użyciu adnotacji zdefiniowanych here, co oznacza, że ​​co najmniej jedno pole ma wartość zerową?Adnotacja sprawdzania poprawności hibernacji - sprawdź, czy co najmniej jedno pole nie ma wartości null

Byłby to hipotetyczny przykład (@OneFieldMustBeNotNullConstraint naprawdę nie istnieje):

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

} 

W przedstawionym przypadku fieldA może być zerowy lub fieldB może być null, ale nie jednocześnie.

Jednym ze sposobów byłoby stworzenie własnego walidatora, ale chciałbym uniknąć, jeśli już istnieje. Udostępnij jeden walidator, jeśli już go masz ... dzięki!

Odpowiedz

13

końcu napisał całą walidator:

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

     } 

} 

Przykład użycia:

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

    @Id 
    @GeneratedValue 
    private Integer id; 

    private Integer fieldA; 
    private Integer fieldB; 

    [...] // accessors, other fields, etc. 
} 
3

Wystarczy napisać własny weryfikator. To nie powinno być proste: przeglądać nazwy pól i uzyskiwać wartości pól za pomocą refleksji.

Concept:

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

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

Nie użyłem metody z commons-beanutils i commons-collections.

+0

Dziękuję, że pomogłeś mi napisać część introspekcję korzystając PropertyUtils.getProperty. – Resh32

Powiązane problemy