Wanneer Hibernate gloede n Sessie, hoe werk dit besluit watter voorwerpe in die sessie is vuil?
Vra
My begrip van Hibernate is dat as voorwerpe is gelaai uit die DB hulle by die sessie. Op verskeie punte, afhangende van jou opset, die sessie is gespoel. Op hierdie punt, is aangepas voorwerpe geskryf om die databasis.
Hoe Hibernate besluit watter voorwerpe 'vuil' is en moet geskryf word?
Voer die gevolmagtigdes wat gegenereer word deur Hibernate onderskep opdragte te velde, en voeg die voorwerp 'n vuil lys in die Sessie?
Of Hibernate kyk na elke voorwerp in die Sessie en vergelyk dit met die oogmerke oorspronklike toestand?
Of iets heeltemal anders?
Oplossing
Hibernate doen / kan bytecode generasie (CGLIB) gebruik sodat dit weet 'n veld is vuil sodra jy die setter noem (of selfs te wys aan die veld afaict).
Dit is vir onmiddellik die veld / voorwerp as vuil, maar nie die aantal voorwerpe wat nodig vuil-gekontroleer tydens spoel te wees verminder. Al wat dit doen is 'n impak die implementering van org.hibernate.engine.EntityEntry.requiresDirtyCheck()
. Dit nog nie 'n veld-vir-veld vergelyking om te kyk vir vuilheid.
Ek sê bogenoemde gebaseer op 'n onlangse treilvissery deur die bronkode (3.2.6GA), met alles wat geloofwaardigheid wat voeg. Punte van belang is:
-
SessionImpl.flush()
snellers 'nonFlush()
gebeurtenis. -
SessionImpl.list()
noemautoFlushIfRequired()
wat 'nonAutoFlush()
geval snellers. (Op die tafels-van-rente). Dit is, navrae kan 'n spoel te roep. Dis interessant dat geen spoel plaasvind indien daar geen transaksie. - Beide dié gebeure uiteindelik beland in
AbstractFlushingEventListener.flushEverythingToExecutions()
, wat eindig (onder andere interessante plekke) byflushEntities()
. - Dit lusse oor elke entiteit in die sessie (
source.getPersistenceContext().getEntityEntries()
) roepDefaultFlushEntityEventListener.onFlushEntity()
. - Jy uiteindelik beland by
dirtyCheck()
. Hierdie metode maak 'n paar optimalisaties tov om vuil vlae CGLIB, maar ons het nog beland herhaling oor elke entiteit.
Ander wenke
Hibernate neem 'n blik op die toestand van elke item wat in die Sessie kry gelaai. Op spoel, is elke item in die Sessie in vergelyking met die ooreenstemmende foto om vas te stel watter vuil is. SQL-stellings uitgereik as wat nodig is, en die foto's is opgedateer om die toestand van die (nou skoon) Sessie voorwerpe reflekteer.
Neem 'n blik op org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck Elke element in die sessie gaan na hierdie metode om te bepaal of dit is vuil of nie deur dit te vergelyk met 'n ongerepte weergawe (een uit die kas of een van die databasis).
Hibernate verstek vuil nagaan meganisme sal deurkruis huidige aangeheg entiteite en pas alle eiendom teen hul aanvanklike laai-time waardes.
Jy kan beter visualiseer hierdie proses in die volgende diagram:
Hierdie antwoorde is onvolledig (op sy beste - ek is nie 'n kenner hier). As jy 'n Hib man entiteit in jou sessie, jy het niks om dit te doen, kan jy nog kry 'n update uitgereik wanneer jy bel red () op dit. wanneer? wanneer 'n ander sessie updates wat beswaar tussen jou vrag () en stoor (). hier is my voorbeeld hiervan: hiberneer stel vuil vlag (en kwessies update) selfs al kliënt nie waarde het verander