2012-08-31 12 views
9

C'è un modo per definire una regola di convalida di Hibernate usando annotazioni come definite here, affermando che almeno un campo deve essere non nullo?Annotazione di convalida di ibernazione: verificare che almeno un campo non sia nullo

questo sarebbe un esempio ipotetico (@OneFieldMustBeNotNullConstraint realtà non esiste):

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

} 

Nel caso illustrato, FieldA può essere nullo o FieldB può essere nulli, ma non entrambe.

Un modo sarebbe creare il mio validatore, ma vorrei evitare se esiste già. Si prega di condividere un validatore se ne avete già uno fatto ... grazie!

risposta

13

ho finalmente scritto l'intero validatore:

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

     } 

} 

Esempio di utilizzo:

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

    @Id 
    @GeneratedValue 
    private Integer id; 

    private Integer fieldA; 
    private Integer fieldB; 

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

Basta scrivere il proprio validatore. Dovrebbe essere piuttosto semplice: eseguire iterazioni sui nomi dei campi e ottenere valori di campo usando la reflection.

Concetto:

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

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

Ci ho usato metodi da commons-beanutils e commons-collections.

+0

Grazie, che mi ha aiutato a scrivere la parte introspezione utilizzando PropertyUtils.getProperty. – Resh32

Problemi correlati