如果hibernate從數據庫中加載兩次,是否會加載同一實例的兩個單獨副本?
不,它不會在同一會話中兩次加載同一個對象(出於我們的理智)。
我創建了一個簡單的Spring Boot project來查看此信息。
EntityA#setOfB(B1,B2)
EntityB#setOfA(A1)
負載EntityA 1和EntityB到會議通過ID後,我們強迫A1.setOfB初始化。 在下面的日誌中我們可以看到,儘管它必須查詢獲得兩行的集合(B1 & B2),但它只會隱藏一個對象(B2),因爲在會話緩存中找到了B1。見測試1(MVN春季啓動:運行-Drun.arguments = 「1」)
DEBUG 6452 --- [ main] o.g.hiplay.app.HibernateService : ########## Retrieving A1's set of B ##########
DEBUG 6452 --- [ main] org.hibernate.SQL : select setofb0_.id_a as id_a1_0_0_, setofb0_.id_b as id_b2_2_0_, entityb1_.id as id1_1_1_, entityb1_.description as descript2_1_1_ from relations setofb0_ inner join entityb entityb1_ on setofb0_.id_b=entityb1_.id where setofb0_.id_a=?
TRACE 6452 --- [ main] o.h.l.p.e.i.AbstractLoadPlanBasedLoader : Bound [2] parameters total
DEBUG 6452 --- [ main] o.h.l.p.e.p.i.ResultSetProcessorImpl : Preparing collection intializer : [oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Constructing collection load context for result set [rs3: [email protected] columns: 4 rows: 2 pos: -1]
TRACE 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Starting attempt to find loading collection [[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]]
TRACE 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Collection not yet initialized; initializing
TRACE 6452 --- [ main] o.h.l.p.e.p.i.ResultSetProcessorImpl : Processing result set
DEBUG 6452 --- [ main] o.h.l.p.e.p.i.ResultSetProcessorImpl : Starting ResultSet row #0
DEBUG 6452 --- [ main] e.p.i.CollectionReferenceInitializerImpl : Found row of collection: [oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]
TRACE 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Starting attempt to find loading collection [[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]]
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Attempting to locate loading collection entry [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] in any result-set context
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Collection [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] located in load context
TRACE 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Found loading collection bound to current result set processing; reading row
TRACE 6452 --- [ main] o.h.e.internal.DefaultLoadEventListener : Loading entity: [oss.gabrielgiussi.hiplay.entities.EntityB#1]
TRACE 6452 --- [ main] o.h.e.internal.DefaultLoadEventListener : Attempting to resolve: [oss.gabrielgiussi.hiplay.entities.EntityB#1]
TRACE 6452 --- [ main] o.h.e.internal.DefaultLoadEventListener : Resolved object in session cache: [oss.gabrielgiussi.hiplay.entities.EntityB#1]
DEBUG 6452 --- [ main] o.h.l.p.e.p.i.ResultSetProcessorImpl : Starting ResultSet row #1
TRACE 6452 --- [ main] l.p.e.p.i.EntityReferenceInitializerImpl : hydrating entity state
TRACE 6452 --- [ main] l.p.e.p.i.EntityReferenceInitializerImpl : Initializing object from ResultSet: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [ main] o.h.p.entity.AbstractEntityPersister : Hydrating entity: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
DEBUG 6452 --- [ main] e.p.i.CollectionReferenceInitializerImpl : Found row of collection: [oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]
TRACE 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Starting attempt to find loading collection [[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]]
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Attempting to locate loading collection entry [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] in any result-set context
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Collection [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] located in load context
TRACE 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Found loading collection bound to current result set processing; reading row
TRACE 6452 --- [ main] o.h.e.internal.DefaultLoadEventListener : Loading entity: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [ main] o.h.e.internal.DefaultLoadEventListener : Attempting to resolve: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [ main] o.h.e.internal.DefaultLoadEventListener : Resolved object in session cache: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [ main] o.h.l.p.e.p.i.ResultSetProcessorImpl : Done processing result set (2 rows)
TRACE 6452 --- [ main] o.h.l.p.e.p.internal.AbstractRowReader : Total objects hydrated: 1
DEBUG 6452 --- [ main] o.h.engine.internal.TwoPhaseLoad : Resolving associations for [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Attempting to locate loading collection entry [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityB.setOfA#2]] in any result-set context
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Collection [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityB.setOfA#2]] not located in load context
TRACE 6452 --- [ main] org.hibernate.type.CollectionType : Created collection wrapper: [oss.gabrielgiussi.hiplay.entities.EntityB.setOfA#2]
DEBUG 6452 --- [ main] o.h.engine.internal.TwoPhaseLoad : Done materializing entity [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Attempting to locate loading collection entry [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] in any result-set context
TRACE 6452 --- [ main] o.h.e.loading.internal.LoadContexts : Collection [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] located in load context
TRACE 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Removing collection load entry [org.hibernate.engine.loading.internal.LoadingCollectionEntry<rs=rs3: [email protected] columns: 4 rows: 2 pos: 2, coll=[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]>@131c8e88]
DEBUG 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : 1 collections were found in result set for role: oss.gabrielgiussi.hiplay.entities.EntityA.setOfB
TRACE 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Ending loading collection [org.hibernate.engine.loading.internal.LoadingCollectionEntry<rs=rs3: [email protected] columns: 4 rows: 2 pos: 2, coll=[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]>@131c8e88]
DEBUG 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : Collection fully initialized: [oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]
DEBUG 6452 --- [ main] o.h.e.l.internal.CollectionLoadContext : 1 collections initialized for role: oss.gabrielgiussi.hiplay.entities.EntityA.setOfB
TRACE 6452 --- [ main] o.h.e.i.StatefulPersistenceContext : Initializing non-lazy collections
DEBUG 6452 --- [ main] o.g.hiplay.app.HibernateService : ########## The object hasn't been loaded twice ##########
休眠檢查是否Object to hydrate已經在會話緩存asking to the StatefulPersistenceContext
我現在想到的是實體B的實例bB也被完全初始化,但是不,它不是,當我引用具有實體A的實例aA的實體B的集合時,我得到延遲初始化異常。
什麼是真正的初始化是BB的集合A的做這樣的事情後:
EntityA AA = session.get( 「A」,A) aA.setOfB.size()//初始化力懶惰的收集。在這一點上,bB是水合性的並且被記憶,但是他收集的A是不合資格的。
如果您嘗試訪問集合Hibernate需要初始化集合(的元素都具有到現在爲止是與負載的智能在需要時從數據庫中的集合,例如請求代理一個元素或集合的大小)。見試驗3(MVN春季啓動:運行-Drun.arguments =「2」)
// outside of the transaction
EntityB bB = aA.setOfB().get(0)
bB.setOfA().size() // LazyInitializationExample
如果你是一個交易的集合將被初始化以及對應於AA行內會再次從基地取回,但不會被水合。見試驗3(MVN彈簧引導:運行-Drun.arguments = 「3」)
用'懶惰= TRUE',裝載'A'將懶惰地加載'B',但在 'B' ,只有標識符會被加載'(ie b。id)',但我們需要使用'HIbernate.intialize(a.getB())'分別初始化lzy集合;' –
這很可能是一個性能低下並且附加值不高的命中。 – Kayaman
你能解釋一下你爲什麼這麼期待嗎?如果我明白了,你期望如果有一件事是懶惰地初始化的,那麼整個會話中的其他事情應該立即初始化? –