2009-11-09 28 views
21

Decir que tengo la siguiente sencilla Java Bean:Java Bean Validation (JSR303) las limitaciones que implican relación entre varias propiedades del bean

class MyBean { 
    private Date startDate; 
    private Date endDate; 
    //setter, getters etc... 
} 

¿Existe un mecanismo en JSR 303 para crear un validador personalizado que valida la restricción de que startDate debe ser antes de endDate?

Me parece que es un caso de uso común, pero no puedo encontrar ningún ejemplo de este tipo de restricción de relaciones de propiedad múltiple.

+1

Se costuras que alguien publicó un ejemplo completo en su blog: http://soadev.blogspot.de/2010/01/jsr-303-bean-validation_29.html – Ralph

Respuesta

27

Puedo pensar en algunas cosas para probar.

Se puede crear un Constraint con un objetivo del tipo en sí con un validador apropiado:

@ValidateDateRange(start="startDate", end="endDate") 
public class MyBean { 

Se puede encapsular un intervalo de fechas en un tipo y validar que:

public class DateRange {  
    private long start; 
    private long end; 

    public void setStart(Date start) { 
    this.start = start.getTime(); 
    } 

    // etc. 

Usted podría Agregue una propiedad simple que realiza el control:

public class MyBean { 
    private Date startDate; 
    private Date endDate; 

    @AssertTrue public boolean isValidRange() { 
    // TODO: null checks 
    return endDate.compareTo(startDate) >= 0; 
    } 
-5

Dado que no hay forma de acceder al bean en un validador JSR 303, esto no es posible.

Una solución alternativa sería proporcionar su propio ConstraintValidatorContext y ampliarlo con una referencia al bean que está validando actualmente. Pero no estoy seguro de si puede modificar/anular la fábrica respectiva.

3

La respuesta es un validador de nivel de clase. Puede definir restricciones personalizadas que puede colocar en la clase de entidad. En el momento de la validación, se pasa la instancia completa al método isValid(). A continuación, puede comparar sus dos fechas cara a cara. Consulte también el Validador de Hibernate documentation.

10

Si está utilizando Hibernate Validator en la versión 4.1 o posterior puede utilizar la restricción @ScriptAssert junto con un lenguaje de script o expresión para expresar este tipo de restricción. Uso de JavaScript tu ejemplo sería el siguiente:

@ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)") 
public class CalendarEvent { 

     private Date startDate; 

     private Date endDate; 

     //... 
} 

Usted puede obtener una sintaxis aún más compacto por creating a custom constraint para el lenguaje de secuencia de comandos de su elección:

@JexlAssert("_.startDate < _.endDate") 
public class CalendarEvent { 

    private Date startDate; 

    private Date endDate; 

    //... 
} 
Cuestiones relacionadas