Interceptory zimného spánku

1. Prehľad

V tejto diskusii sa pozrieme na rôzne spôsoby zachytávania operácií v implementácii abstrahovaného relačného mapovania Hibernate.

2. Definovanie zachytávačov hibernácie

Hibernate Interceptor je rozhranie, ktoré nám umožňuje reagovať na určité udalosti v rámci režimu dlhodobého spánku.

Tieto zachytávače sú registrované ako spätné volania a poskytujú komunikačné spojenia medzi reláciou dlhodobého spánku a aplikáciou. Pomocou takéhoto spätného volania môže aplikácia zachytiť základné operácie režimu dlhodobého spánku, ako sú ukladať, aktualizovať, mazať atď.

Existujú dva spôsoby definovania zachytávačov:

  1. implementácia org.hibernate.Interceptor rozhranie
  2. predĺženie org.hibernate.EmptyInterceptor trieda

2.1. Vykonávanie Stíhačka Rozhranie

Implementácia org.hibernate.Interceptor vyžaduje implementáciu asi 14 sprievodných metód. Tieto metódy zahŕňajú onLoad, onSave, onDelete, findDirty, a niekoľko ďalších.

Je tiež dôležité zabezpečiť, aby každá trieda, ktorá implementuje rozhranie Interceptor, bola serializovateľná (implementuje java.io.Serializovateľné).

Typický príklad by vyzeral takto:

verejná trieda CustomInterceptorImpl implementuje Interceptor, Serializable {@Override public boolean onLoad (Object entity, Serializable id, Object [] state, String [] propertyNames, Type [] types) throws CallbackException {// ... return false; } // ... @Override public String onPrepareStatement (String sql) {// ... return sql; }}

Ak neexistujú žiadne špeciálne požiadavky, predĺženie EmptyInterceptor triedy a dôrazne sa odporúča iba prekonanie požadovaných metód.

2.2. Predĺženie EmptyInterceptor

Predĺženie org.hibernate.EmptyInterceptor trieda poskytuje ľahší spôsob definovania zachytávača. Teraz musíme prepísať iba tie metódy, ktoré sa týkajú operácie, ktorú chceme zachytiť.

Napríklad môžeme definovať náš CustomInterceptor ako:

verejná trieda CustomInterceptor rozširuje EmptyInterceptor {}

A ak potrebujeme zachytiť operácie ukladania údajov pred ich vykonaním, musíme prepísať onSave metóda:

@Override public boolean onSave (Object entity, Serializable id, Object [] state, String [] propertyNames, Type [] types) {if (entity instanceof User) {logger.info (((User) entity) .toString ()) ; } návrat super.onSave (entita, id, štát, propertyNames, typy); }

Všimnite si, ako táto implementácia jednoducho vytlačí entitu - ak je Používateľ.

Aj keď je možné vrátiť hodnotu pravda alebo nepravdivé, je dobrým zvykom povoliť šírenie onSave udalosť vyvolaním super.onSave ().

Ďalším prípadom použitia by bolo poskytnutie záznamu o audite pre databázové interakcie. Môžeme použiť onFlushDirty () metóda vedieť, kedy sa jednotka zmení.

Pre Používateľ objektu sa môžeme rozhodnúť aktualizovať jeho naposledy zmenené vlastnosť dátumu vždy, keď sa zmeny na entitách typu Používateľ stať sa.

To sa dá dosiahnuť pomocou:

@Override public boolean onFlushDirty (Object entity, Serializable id, Object [] currentState, Object [] previousState, String [] propertyNames, Type [] types) {if (entity instanceof User) {((User) entity) .setLastModified (new Dátum()); logger.info ((((User) entity) .toString ()); } návrat super.onFlushDirty (entita, id, currentState, previousState, propertyNames, typy); }

Ostatné udalosti ako napr vymazať a naložiť (inicializácia objektu) je možné zachytiť implementáciou zodpovedajúceho onDelete a onLoad metódy resp.

3. Registrácia Interceptory

Zachytávač dlhodobého spánku je možné zaregistrovať ako Session-scoped alebo Rozsah SessionFactory.

3.1. Interceptor s rozsahom relácie

A Sessionzachytený zachytávač je prepojený s konkrétnou reláciou. Vytvára sa pri definovaní alebo otvorení relácie ako:

public static Session getSessionWithInterceptor (Interceptor interceptor) hodí IOException {return getSessionFactory (). withOptions () .interceptor (interceptor) .openSession (); }

Vo vyššie uvedenom prípade sme výslovne zaregistrovali zachytávač s konkrétnou hibernáciou.

3.2. SessionFactory-scoped Stíhačka

A SessionFactory-zachytený rozsah je zachytený pred vybudovaním a SessionFactory. Toto sa zvyčajne vykonáva prostredníctvom applyInterceptor metóda na a SessionFactoryBuilder inštancia:

ServiceRegistry serviceRegistry = configureServiceRegistry (); SessionFactory sessionFactory = getSessionFactoryBuilder (serviceRegistry) .applyInterceptor (nový CustomInterceptor ()) .build ();

Je dôležité si uvedomiť, že a SessionFactory-zachytávač s rozsahom sa použije na všetky relácie. Preto musíme byť opatrní, aby sme neukladali stav špecifický pre reláciu - pretože tento zachytávač budú používať rôzne relácie súčasne.

Pre správanie špecifické pre reláciu sa odporúča explicitne otvoriť reláciu s iným zachytávačom, ako je uvedené vyššie.

Pre SessionFactoryzachytávače, musíme sa samozrejme ubezpečiť, že sú bezpečné pre vlákna. To sa dá dosiahnuť zadaním kontextu relácie v súbore vlastností:

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

Alebo pridaním tohto do nášho konfiguračného súboru XML:

 org.hibernate.context.internal.ThreadLocalSessionContext 

Na zabezpečenie serializovateľnosti tiež SessionFactory- zachytené záchytné systémy musia implementovať readResolve metóda Serializovateľné rozhranie.

4. Záver

Už sme videli, ako definovať a zaregistrovať zachytávače hibernácie ako Session-scoped alebo SessionFactory-scoped. V obidvoch prípadoch musíme zabezpečiť, aby zachytávače boli serializovateľné, najmä ak chceme serializovateľnú reláciu.

Medzi ďalšie alternatívy k zachytávačom patria udalosti dlhodobého spánku a spätné volania JPA.

A ako vždy, môžete si pozrieť kompletný zdrojový kód na stránkach Github.


$config[zx-auto] not found$config[zx-overlay] not found