Допустим, я получил объект Employee 'e', используя session.get с Hibernate, чей идентификатор равен 101. Теперь я выполнил запрос HQL, который извлекает всю занятость (из Employee e) , Обе вышеупомянутые операции выполняются на одном сеансе. Будет создан новый объект Employee для того, который был получен с помощью запроса, или будет добавлен «e» в список результатов, так что будет только одна копия сотрудника с идентификатором 101.Hibernate - кэширование первого уровня и HQL
ответ
При выполнении session.get()
1.) Запрос будет запущен в БД для получения Employee
на основе identifier 101
.
2.) Объект будет помещен в кеш 1-го уровня или уровень сеанса.
Пожар запроса, где (101,Employee)
является частью записей выборки.
1.) Спящий режим будет просто извлекать идентификаторы с первого раза.
2.) Затем найдите каждый идентификатор в кеше (1st Level + 2nd level)
, если он есть, объект будет извлечен из кэша, иначе для извлечения объекта будет запущен отдельный запрос.
В дополнение к тому, что уже упоминалось в 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();
Если включить журналы отладки, вы увидите что-то вроде этого - как вы можете видеть, что первые попытки Hibernate для загрузки объекта из первых/кэша второго уровня, а затем запускает 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. Hibernate кэширование второго уровня
- 2. Hibernate HQL: два уровня присоединяется
- 3. Hibernate Кэш первого уровня
- 4. Кэш первого уровня в Hibernate
- 5. Hibernate кеш первого уровня и метод get
- 6. Hibernate OGM и Hibernate OGM кеш первого и второго уровня
- 7. Hibernate HQL и наследование
- 8. Hibernate, Maps и HQL
- 9. Наследование Hibernate и HQL
- 10. Hibernate HQL и Date
- 11. как hibernate выполняет механизм кэширования, какова разница между кешем первого уровня и кэшем второго уровня.
- 12. Hibernate кеш первого уровня - это синхронизация?
- 13. Кэширование Spring-Hibernate с Memcached
- 14. Hibernate (HQL)
- 15. Hibernate HQL CreateQuery
- 16. Рабочий пример Hibernate 3.6.2 Кэширование 2-го уровня с JPA2?
- 17. Jhipster Multi-tenancy с Hibernate второго уровня Кэширование
- 18. Hibernate - ассоциация второго уровня
- 19. В чем разница между приемом EntityManager JPA и кэшированием первого уровня Hibernate?
- 20. Кэширование уровня браузера
- 21. HQL vs. SQL/Hibernate netbeans Редактор HQL
- 22. Атрибуты списка Hibernate HQL?
- 23. Reindexing with hibernate/HQL
- 24. Hibernate: HQL не работает
- 25. Hibernate наследования HQL типа
- 26. Hibernate условное соединение HQL
- 27. GROUP_CONCAT Hibernate HQL
- 28. Hibernate HQL запрос
- 29. Hibernate HQL запрос - сложный
- 30. Hibernate HQL вложенного запроса