假設我已經使用session.get與Hibernate的id爲101的Employee對象'e'。現在,我執行了一個HQL查詢,它檢索所有employess(來自Employee e) 。上述操作都是在同一個會話中完成的。將爲使用查詢檢索到的新對象創建新的Employee對象,還是隻會將'e'添加到結果列表中,以便只有一個員工ID爲101的副本。休眠 - 一級緩存和HQL
1
A
回答
1
執行時session.get()
1.)查詢將在DB中觸發,以基於identifier 101
獲取Employee
。
2.)該對象將被放入一級緩存或會話級別。
啓動一個查詢,其中(101,Employee)
是提取記錄的一部分。
1)hibernate只會在第一時間獲取標識符。
2.)然後查找緩存中的每個標識符(1st Level + 2nd level)
,如果存在,將從緩存中獲取對象,否則會觸發單獨的查詢來獲取對象。
1
加入Ankur已經提到的內容 - 讓我們看看底下發生了什麼。我使用JPA API,但概念相同,基礎持久性提供程序是Hibernate。
@Entity
public class TestEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
//getter/setters
}
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
TestEntity te = em.find(TestEntity.class, new Long(1));
Query query = em
.createQuery("select testEntity from TestEntity testEntity where testEntity.id =:id");
query.setParameter("id", new Long(1));
TestEntity te1 = (TestEntity) query.getSingleResult();
em.getTransaction().commit();
em.close();
如果啓用調試日誌,你會看到這樣的事情 - 你可以看到,首先休眠企圖從 第一/第二級緩存加載實體,然後觸發的SQL來獲取數據。更有趣的是,在對應於HQL(JPQL)的查詢被觸發後,hibernate不會嘗試創建任何對象,實際上它將返回相同的實例以在其會話中維護單個副本。
10:56:40.292 [main] TRACE o.h.e.i.DefaultLoadEventListener [DefaultLoadEventListener.java:251]- Loading entity: [com.test.TestEntity#1]
10:56:40.293 [main] TRACE o.h.e.i.DefaultLoadEventListener [DefaultLoadEventListener.java:425]- Attempting to resolve: [com.test.TestEntity#1]
10:56:40.293 [main] TRACE o.h.e.i.DefaultLoadEventListener [DefaultLoadEventListener.java:463]- Object not resolved in any cache: [com.test.TestEntity#1]
10:56:40.303 [main] INFO - select testentity0_.id as id1_11_0_, testentity0_.name as name2_11_0_ from test_entity testentity0_
where testentity0_.id=1
10:56:40.318 [main] DEBUG o.h.engine.internal.TwoPhaseLoad [TwoPhaseLoad.java:160]- Resolving associations for [com.test.TestEntity#1]
10:56:40.321 [main] DEBUG o.h.engine.internal.TwoPhaseLoad [TwoPhaseLoad.java:286]- Done materializing entity [com.test.TestEntity#1]
10:56:40.573 [main] INFO /* select testEntity from TestEntity testEntity where testEntity.id =:id */ select testentity0_.id
as id1_11_, testentity0_.name as name2_11_ from test_entity testentity0_ where testentity0_.id=1
現在讓我們來看看,如果我刪除查找調用會發生什麼 - 這一次使用從HQL查詢返回的數據創建實體
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Query query = em
.createQuery("select testEntity from TestEntity testEntity where testEntity.id =:id");
query.setParameter("id", new Long(1));
//em.persist(testEntity);
TestEntity te1 = (TestEntity) query.getSingleResult();
em.getTransaction().commit();
em.close();
11:00:30.159 [main] INFO /* select testEntity from TestEntity testEntity where testEntity.id =:id */ select testentity0_.id
as id1_11_, testentity0_.name as name2_11_ from test_entity testentity0_ where testentity0_.id=1
11:00:30.178 [main] DEBUG o.h.engine.internal.TwoPhaseLoad [TwoPhaseLoad.java:160]- Resolving associations for [com.test.TestEntity#1]
11:00:30.182 [main] DEBUG o.h.engine.internal.TwoPhaseLoad [TwoPhaseLoad.java:286]- Done materializing entity [com.test.TestEntity#1]
相關問題
- 1. 休眠:一級緩存
- 2. 休眠:batch_size?二級緩存?
- 3. 休眠二級緩存
- 4. 休眠二級緩存
- 5. 休眠緩存級別1
- 6. 休眠二級緩存和關聯
- 7. 共享nHibernate和休眠二級緩存
- 8. 使用休眠一級緩存
- 9. 一級休眠緩存,直接在DB
- 10. 休眠二級緩存,一對多
- 11. 休眠第一級高速緩存
- 12. 休眠一級高速緩存
- 13. 新手休眠一級緩存混淆
- 14. 休眠OGM和Hibernate OGM一級和二級緩存
- 15. 休眠HQL和setMaxResults
- 16. 休眠緩存
- 17. 休眠查詢緩存和二級緩存
- 18. 休眠第二級緩存和一對一的關係
- 19. 休眠HQL getMaxVersion
- 20. GROUP_CONCAT休眠HQL
- 21. 休眠(HQL)
- 22. 休眠SQL,HQL和Criteria API
- 23. 休眠HQL和日期
- 24. 休眠,取,HQL和hashCode()
- 25. 休眠,地圖和HQL
- 26. 設置休眠第二級緩存
- 27. 休眠:麻煩啓用二級緩存
- 28. 休眠二級緩存示例
- 29. Spring-Boot - 激活休眠二級緩存
- 30. 休眠二級緩存更新