vincolo univoco con JPA e Bean Validation
-
29-09-2019 - |
Domanda
Mi piacerebbe avere un vincolo @Unique
con Bean Validation, ma che non è previsto dalla norma. Se dovessi usare @UniqueConstraint
dell'APP non avrei un meccanismo di convalida e di segnalazione degli errori unico.
C'è un modo per definire @Unique
come un vincolo Bean Validation e combinarlo con APP, in modo tale che APP crea una colonna con un vincolo unico e controlli wheter un valore unico o no?
Soluzione
A meno che non si acquista un blocco su un'intera tabella , è fondamentalmente non è possibile verificare la presenza di unicità utilizzando una query SQL (qualsiasi transazione concorrente potrebbe modificare i dati dopo un controllo manuale, ma prima che il commit della operazione in corso). In altre parole, non è possibile implementare una verifica unica valida a livello Java e quindi di fornire un'implementazione di convalida. L'unico modo affidabile per verificare la presenza di unicità è, mentre il commit della transazione.
Il BV spec riassume in questo modo:
Appendice D. Java Persistence integrazione 2.0
Domanda: dovremmo aggiungere che @Unique sarebbe mappare @Column (unica = true)?
@Unique non può essere testato in Java livello di affidabilità, ma potrebbe generare un database di generazione vincolo univoco. @Unique non è parte della specifica BV oggi.
Così, mentre sono d'accordo che sarebbe stato bello avere (nullo e non) unica violazioni dei vincoli avvolti in un'eccezione Bean Validation, questo non è il caso attualmente.
Bibliografia
- specifica Bean Validation (JSR 303)
- Domanda sulla convalida e la persistenza dei vincoli
Altri suggerimenti
Maggiori informazioni su come implementare un @Unique e la problematica intorno ad esso può essere trovato qui - http: / /community.jboss.org/wiki/AccessingtheHibernateSessionwithinaConstraintValidator
Beh si può fare, ma non è banale. Il problema è: il validatore richiede l'accesso database per eseguire alcune query di controllo, se il valore si desidera inserire è già lì o no. E questo non può essere fatto veramente dal validatore, in quanto non ha accesso al sessionFactory / sessione. Naturalmente si potrebbe un'istanza (sessione / sessionFactory) all'interno del validatore, ma non è una buona pratica di codifica.
Si può fare un validatore leggere le annotazioni APP e applicarlo. Qui è piuttosto di un esempio utilizzando validatori molla che possono essere utilizzati come idea di espandere.
Modulo JPA JSR303 Primavera convalida
Si può anche iniettare (@Inject
o @Autowired
Primavera) il bean di sessione in un validatore personalizzato e il contenitore deve sapere come collegare l'alto. So solo questo come un esempio di primavera:
import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
@Autowired //@Inject
private Foo aDependency;
...
}