Hibernált interceptorok

1. Áttekintés

Ebben a megbeszélésben a műveletek lehallgatásának különböző módjait vizsgáljuk meg a Hibernate elvont relációs leképezési megvalósításán belül.

2. A hibernált interceptorok meghatározása

A Hibernate Interceptor egy olyan felület, amely lehetővé teszi számunkra, hogy reagáljunk a Hibernate bizonyos eseményeire.

Ezek az elfogók visszahívásokként vannak regisztrálva, és kommunikációs kapcsolatokat biztosítanak a Hibernate munkamenete és az alkalmazás között. Ilyen visszahívással egy alkalmazás képes lehallgatni a Hibernate alapvető műveleteit, mint pl mentés, frissítés, törlés stb.

Az elfogók meghatározásának két módja van:

  1. a org.hibernate.Interceptor felület
  2. kiterjesztve a org.hibernate.EmptyInterceptor osztály

2.1. Egy Elfogó Felület

Végrehajtás org.hibernate.Interceptor körülbelül 14 kísérő módszer bevezetését igényli. Ezek a módszerek magukban foglalják onLoad, onSave, onDelete, findDirty, és még néhány.

Fontos annak biztosítása is, hogy minden osztály, amely az Interceptor interfészt alkalmazza, sorosítható legyen (megvalósítja a java.io.Serializable).

Egy tipikus példa a következőképpen néz ki:

public class CustomInterceptorImpl implementálja Interceptor, Serializable {@Orride public boolean onLoad (Object entity, Serializable id, Object [] state, String [] propertyNames, Type [] types) dob CallbackException {// ... return false; } // ... @Orride public String onPrepareStatement (String sql) {// ... return sql; }}

Ha nincsenek külön követelmények, kiterjesztve a EmptyInterceptor osztályban, és csak a szükséges módszerek felülbírálása erősen ajánlott.

2.2. Kiterjedő EmptyInterceptor

A. Kiterjesztése org.hibernate.EmptyInterceptor osztály az elfogó meghatározásának egyszerűbb módját nyújtja. Most már csak azokat a módszereket kell felülírnunk, amelyek kapcsolódnak az elfogni kívánt művelethez.

Például meghatározhatjuk CustomInterceptor mint:

public class CustomInterceptor kiterjeszti az EmptyInterceptor {}

És ha végrehajtásuk előtt meg kell fognunk az adatmentési műveleteket, akkor felül kell írnunk onSave módszer:

@Orride public boolean onSave (Object entitás, Serializable id, Object [] állapot, String [] tulajdonságnév, Type [] típusok) {if (Felhasználó entitás példánya) {logger.info ((((Felhasználó) entitás) .toString ()) ; } return super.onSave (entitás, id, állapot, tulajdonságNevek, típusok); }

Figyelje meg, hogy ez az implementáció hogyan nyomtatja ki egyszerűen az entitást - ha a Felhasználó.

Bár vissza lehet adni egy értéket igaz vagy hamis, jó gyakorlat engedélyezni a onSave esemény meghívásával super.onSave ().

Egy másik felhasználási eset az audit-nyomvonal biztosítása lenne az adatbázis-interakciókhoz. Használhatjuk a onFlushDirty () módszer, hogy megtudjuk, mikor változik az entitás.

A Felhasználó objektum, dönthetünk annak frissítéséről utoljára módosítva date tulajdonság, amikor a típusú entitásokon megváltozik Felhasználó történik.

Ez az alábbiakkal érhető el:

@Orride public boolean onFlushDirty (Object entity, Serializable id, Object [] currentState, Object [] previousState, String [] propertyNames, Type [] types) {if (Felhasználó entitás példánya) {((Felhasználó) entitás). SetLastModified (új Dátum()); logger.info (((Felhasználó) entitás) .toString ()); } return super.onFlushDirty (entitás, id, currentState, előzőState, tulajdonságNevek, típusok); }

Egyéb események, mint pl töröl és Betöltés (objektum inicializálása) a megfelelő végrehajtásával lehallgatható onDelete és Feltöltés alatt módszerek.

3. Regisztráció Elfogók

A hibernált elfogót vagy regisztrálhatjuk Ülés-hopp vagy SessionFactory hatókörű.

3.1. Munkamenet hatókörű elfogó

A Ülés- a lefoglalt elfogó egy adott munkamenethez kapcsolódik. Akkor jön létre, amikor a munkamenet meghatározása vagy megnyitása a következő:

public static Session getSessionWithInterceptor (Interceptor interceptor) dobja az IOException-t {return getSessionFactory (). withOptions (). interceptor (interceptor) .openSession (); }

A fentiekben kifejezetten regisztráltunk egy elfogót egy adott hibernált munkamenetben.

3.2. SessionFactory- fedett Elfogó

A SessionFactory-hatókörű elfogót az a megépítése előtt regisztrálják SessionFactory. Ezt általában a ApplyInterceptor módszer a SessionFactoryBuilder példa:

ServiceRegistry serviceRegistry = configureServiceRegistry (); SessionFactory sessionFactory = getSessionFactoryBuilder (serviceRegistry) .applyInterceptor (új CustomInterceptor ()) .build ();

Fontos megjegyezni, hogy a SessionFactory-hatókörű elfogót alkalmazzák az összes munkamenetre. Ezért arra kell figyelnünk, hogy ne tároljuk a munkamenet-specifikus állapotot - mivel ezt az elfogót különböző munkamenetek egyidejűleg fogják használni.

Munkamenet-specifikus viselkedés esetén ajánlott kifejezetten egy másik elfogóval nyitni egy munkamenetet, amint azt korábban bemutattuk.

Mert SessionFactory- lefoglalt elfogók, természetesen biztosítanunk kell, hogy szálbiztos legyen. Ez úgy érhető el, hogy a tulajdonságfájlban megad egy munkamenet-kontextust:

hibernate.current_session_context_class = org.hibernate.context.internal.ThreadLocalSessionContext

Vagy hozzáadva ezt az XML konfigurációs fájlunkhoz:

 org.hibernate.context.internal.ThreadLocalSessionContext 

A szerializálhatóság biztosítása érdekében SessionFactory- a lefoglalt elfogóknak végre kell hajtaniuk a readResolve módszere Sorosítható felület.

4. Következtetés

Láthattuk, hogyan definiálhatjuk és regisztrálhatjuk a hibernált elfogókat is Ülés-hopp vagy SessionFactory- fedett. Mindkét esetben biztosítanunk kell az elfogók sorosíthatóságát, különösen akkor, ha sorosítható munkamenetet szeretnénk.

Az elfogók további alternatívái a hibernált események és a JPA visszahívások.

És mint mindig, a teljes forráskódot megnézheti a Githubon.