Child pages
  • Bean validation - UniqueConstraintValidator
Skip to end of metadata
Go to start of metadata

Készítek egy saját bean validátort (jsr-303), ami az insertnél futna le és ellenőrizné, hogy a megadott felhasználónévvel létezik-e már user. A Validation Class-ba, ezért beinjektáltam egy EJB service-t, melyet meghívok és visszaadna, egy true vagy false értéket. A problémám az, ha a servicem az EntityManager find metódusát hívja meg, akkor mivel a Validation a persist meghívása után hívódik automatikusan, ezért az EM cacheből vissza adja saját magát, hogy igen már létezik, persze csak a validation lefutása után létezhetne valójában a db-ben is. Ezért próbálkoztam Hibernate NamedQuery-vel, ott megadható a cachelés (CacheModeType), viszont így betöltésnél, lefuttatná a betöltött Entitásra is a validációt és így egy végtelen ciklusba kerül. Próbáltam a persistence.xml javax.persistence.validation.group.pre-update és javax.persistence.validation.group.pre-persist-hez group-ot és a validátoromhoz is groupot rendelni, de nem segített. Persze megoldhatnám másképp is ezt a dolgot, de a jsr-303-at pont ezért találták ki. (smile) Ahol elakadtam: Az EM find-ra nem lehet valahogy kikapcsolni a cachelést? (Bár ez Hibernate NamedQuery-vel úgy néz ki megoldódott) A Query lefutására nem lehetne valahogy kikapcsolni a validációt?

 

      
      
Page viewed times
#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))
  • No labels

9 Comments

  1. Közben jött egy ötlet, hogy mi lenne, ha a TransactionAttributeType-ot átállítanám a service-ben? Bejött! Ez lett a megoldás.

    1. Az ember néha már azzal sokat segít magán, ha megfogalmazza a problémát... (smile)

  2. Azt hadd kérdezzem már meg, hogy miért a persist után hívódik meg a validation? Nem úgy kéne működnie, ha nem érvényes egy entitás, akkor nem is próbálod beszúrni?

  3. Lehet félreértettél, vagy rosszul írtam. nem persist után, hanem persist alatt hívódik meg.

    Nekem a debug szerint úgy működik, hogy az Entitymanager persist metódusa után bekerül az EntityManager cache-be és a persist persze hívja/futtatja a validátorokat, de az egyik Validatoromba be kellett injektáljak egy EJB bean-t(mellyel lekérdezem, hogy létezik-e már a usernév), mely kezdetben megörökölte a tranzakció vezérlést és ezáltal az Entitymanager cache-t is a persist-et hívó EJB-től és ez volt a problémám, hogy hiába ellenőrizte a Validator EJB-m find-al, hogy létezik-e, mert a cache-ben ott volt amire még nem futott le a tranzakció, így mindig azt dobta, hogy létezik. (smile)

    1. Csodás, ennek tényleg így kell működnie. (sad) Csak kíváncsiság miatt érdekelne, hogy mi lenne, ha tennél egy olyan feltételt is bele, hogy ahol az id nem egyelő a perzisztálni kívánt entitás id-jával. Vagy ilyenkor még nem is ad neki id-t, és így teszi a cache-be? Vagy ha ad neki, de elbukik a validáció, akkor ugrott az az id?

  4. Igen, igazad van, erre is gondoltam... utólag... (smile) de amikor az entitásokat terveztem, úgy gondoltam, hogy lehet a loginname unique, így nincs id-m. (smile) Egyébként egy másik projektemben pont így vizsgálok egyediséget, ahogy leírtad. (smile) Pont ezért gondoltam, hogy "helytakarékosság" miatt nem lesz id-m (smile)

    1. Mostanság egy 4-8 bájtos id mező nem igazán segít a helytakarékosságban... ellenben sokat segít, ha van... (smile)

      1. Hát igen, csak arra is gondoltam, hogy ha nekem a loginname lenne az id-m, akkor nem kell indexelnem, hanem mivel id, automatikusan indexelt. Míg, ha nem az lenne, akor külön kellene indexelni. Nem nagy különbségek, ízlések és pofonok... (smile)

        jah, és így em.find()-ot használhatok kersésre, nem kell semmi hókuszpók. (smile) De ez se akkora nagy feature/elöny, de mégis valami (smile)

  5. lenne egy olyan kérdésem is, hogy szeretném a Hibernate OGM-et glassfish alá Cassandra-val bekonfigurálni. 3 féle képpen próbálkoztam:

    1, Felveszem a persistence-unit-ot a persistence xml-be és a @PersistenceContext-el berántom, ahol kell. Ennél ott akadtam el, hogy nem tudom, hogyan kell NoSQL-es pool-t a glassfishbe bekonfigolni. Gondolom a lib-je alá kell tenni a hector-t, mint driver-t és valahol megadni a pool adatait, node hol? Gondolom nem a jdbc alarr, de akkor Connectors vagy a Resource Adapters alatt? Vagy kellen írjak valami saját modul-t glassfish alá, ami betölti?

    2, próbálkoztam a Persistence.createEntityManagerFactory-val és gondoltam ahova teszek egy @Inject-et, oda CDI-al beteszi majd ezt a @Singletone Entitymanager-t. Node elfelejtettem, hogy ugye a Glassfish alatt ő manageli az adatforrásokat, így a createEntityManagerFactory-ra kaptam egy szép exception-t. (smile)

    3, Hát végül nem OGM, hanem sima hector... A logika megegyezik a 2-es ponttal, csak @Inject-re a a hector-al felépített EntityManagert kézzel hozom létre a hector new EntitymanagerImpl-el.

     

    A kérdés inkább az elsőre vonatkozik csak, hogy hogyan lehetne a glassfisht felkonfgolni, hogy az OGM persistence-unit-ot @PersistenceContext-el betöltse?