Ahoj,
problem je, ze pouzivate v UI primo managed entitu a pri commitu
transakce dojde k ulozeni stavu z objektu do databaze (flush).
Reseni jsou dve:
a) neposilat managed entitu az do UI v pripade modifikujicich operaci
- pouzijte specialni DTO
b) detachnete danou entitu od EntityManageru - tj. nepouzivejte
session in view navrhovy vzor
(v pripade primeho pouziti Hibernate je mozne zavolat
session.evict())
(nedoporucuji volat clear() na EM, protoze to muze udelat pekny
zmatek v jinych castech aplikace...)
Lukas
BTW: volani metody merge() (coz je IMHO kod uvnitr vasi metody save())
na managed entitu nema valny smysl.
tomas napsal(a):
Dobrý den
mám následující problém, který se vyskytne při validaci formulářů ve
webové aplikací, která používá Spring, Struts2, Jpa(Hibernate).
Mám DAO třídu (service), která používá EntityManagera a transakce
(@Transactional). Abych mohl načítat asociované objety ve view vrstvě,
mám ve web.xml registrovaný filtr OpenEntityManagerInViewFilter.
1. Vyplním formulář a odešlu na StrutsAction.java
//pole ve formuláři
<input type="hidden" name="article.id" value="2" />
<input name="article.title" />
2. Ve tříde StrutsAction se mi podle article.id natáhne z db entita a
přes set metodu se do ní vloží titulek (Article.title)
//načtení entity z db
//a asi start transakce
if (article != null && article.getId() != null)
article = service.find(article.getId());
3. Spustí se validační interceptor, který kontroluje délku stringu
titulku (schválně jsem ho zadal delší než je povolené) a protože titulek
je delší vrací mě na formulář. Metoda save která obsahuje
"service.save(article);" se nespustí což je v pořádku.
@ValidujDelku
public String save() throws Exception{
service.save(article);
return SUCCESS;
}
Problém(aneb co si myslím, že se děje):
4. Před tím než OpenEntityManagerInViewFilter uzavře transakci zavolá
metodu flush a synchronizuje objekt Article načtený ve StrutsAction s
DB. (Objekt Article obsahuje pole title s přesahující délkou pole)
5. Hibernate mi vyhodí vyjímku
BatchUpdateException: Data truncation: Data too long for column 'title'
at row 1
Problém tedy vidím v automatické synchronizaci objektu Article. ???
FlushModeType.AUTO
Stále se v tom hrabu a nemůžu přijít na to kde, co a jak změnit.
Děkuju za radu.
Tomáš