2015-05-05 2 views
1

Допустим, я получил объект Employee 'e', ​​используя session.get с Hibernate, чей идентификатор равен 101. Теперь я выполнил запрос HQL, который извлекает всю занятость (из Employee e) , Обе вышеупомянутые операции выполняются на одном сеансе. Будет создан новый объект Employee для того, который был получен с помощью запроса, или будет добавлен «e» в список результатов, так что будет только одна копия сотрудника с идентификатором 101.Hibernate - кэширование первого уровня и HQL

ответ

1

При выполнении session.get()

1.) Запрос будет запущен в БД для получения Employee на основе identifier 101.

2.) Объект будет помещен в кеш 1-го уровня или уровень сеанса.

Пожар запроса, где (101,Employee) является частью записей выборки.

1.) Спящий режим будет просто извлекать идентификаторы с первого раза.

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(); 

Если включить журналы отладки, вы увидите что-то вроде этого - как вы можете видеть, что первые попытки 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] 
Смежные вопросы