custom - javax.validation example
Restricción única con JPA y validación de frijol (4)
Me gustaría tener una restricción @Unique
con Bean Validation, pero eso no lo proporciona el estándar. Si utilizara el @UniqueConstraint
de JPA, no tendría un mecanismo único de validación e informe de errores.
¿Existe alguna manera de definir @Unique
como una restricción de Validación de Frijol y combinarlo con JPA, de modo que JPA cree una columna con una restricción única y verifique si un valor es único o no?
Bueno, puedes hacerlo, pero no es trivial. El problema es que el validador requiere acceso a la base de datos para realizar algunas consultas para verificar, si el valor que desea insertar ya está allí o no. Y esto no se puede hacer realmente desde el validador, ya que no tiene acceso a sessionFactory / session. Por supuesto, podría instanciarlo (session / sessionFactory) dentro del validador, pero no es una buena práctica de codificación.
Puede encontrar más información sobre cómo implementar un @Unique y la problemática que lo rodea aquí - http://community.jboss.org/wiki/AccessingtheHibernateSessionwithinaConstraintValidator
Puede hacer que un validador lea las anotaciones JPA y aplicarlas. Aquí hay algo de ejemplo usando validadores de primavera que se pueden usar como una idea para expandir.
JPA JSR303 Spring Form Validation
También puede inyectar ( @Inject
o Spring''s @Autowired
) su bean de sesión en un validador personalizado y el contenedor debe saber cómo conectarlo. Solo sé esto como un ejemplo de primavera:
import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
@Autowired //@Inject
private Foo aDependency;
...
}
A menos que adquiera un bloqueo en una tabla completa , básicamente no es posible verificar la unicidad mediante una consulta SQL (cualquier transacción simultánea podría modificar los datos después de una verificación manual pero antes de la confirmación de la transacción en curso). En otras palabras, no es posible implementar una verificación única válida en el nivel de Java y así proporcionar una implementación de validación. La única manera confiable de verificar la unicidad es al comprometer la transacción.
La especificación BV lo resume así:
Apéndice D. Integración de Java Persistence 2.0
Pregunta: ¿deberíamos agregar @Unique que se correlacionaría con @Column (unique = true)?
@Unique no se puede probar en el nivel de Java de manera confiable, pero podría generar una generación de restricción única en la base de datos. @Unique no es parte de la especificación BV hoy.
Entonces, aunque estoy de acuerdo en que sería bueno tener violaciones de restricciones únicas (y no nulas) envueltas en una excepción de Validación de frijoles, este no es el caso actualmente.
Referencias
- Especificación de validación de frijol (JSR 303)
- Pregunta sobre validación y restricciones de persistencia