У меня есть простой проект, который я использую для изучения Hibernate и JPA. У меня есть проект, настроенный и работающий, с возможностью сохранения данных persist () в базе данных (HSQLDB) и возврата данных createQuery ().
Я включил параметр show_sql в persistence.xml, чтобы увидеть, что происходит под ним. Я не понимаю, почему каждый раз, когда я запрашиваю данные, выполняется SQL-запрос, даже если не выполнялась никакая другая транзакция / коммит.
Я использую один EntityManager, созданный с помощью Persistence.createEntityManagerFactory () в методе класса, вызванного моим сервлетом. Когда это создается, я вызываю em.setFlushMode (FlushModeType.COMMIT).
public class ThingPersist {
private static EntityManagerFactory emf;
private static EntityManager em;
public static EntityManager getEntityManager()
{
if (emf == null)
emf = Persistence.createEntityManagerFactory("thingPersist");
if (em == null)
{
em = emf.createEntityManager();
em.setFlushMode(FlushModeType.COMMIT);
}
return em;
}
}
Метод doGet () моего сервлета запрашивает данные (класс Thing имеет переопределения hashCode () и equals ()):
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
EntityManager em = ThingPersist.getEntityManager();
em.setFlushMode(FlushModeType.COMMIT);
List<Thing> things = em.createQuery("from Thing", Thing.class).getResultList();
for (Thing thing : things)
response.getWriter().println(thing.getSomeString());
}
Hibernate затем показывает следующий SQL:
Hibernate:
select
thing0_.id as id0_,
thing0_.someString as someString0_
from
Thing thing0_
Если я снова вызываю сервлет, выполняется тот же SQL. Если сразу после этого я добавлю другой идентичный блок createQuery (), Hibernate сообщит, что один и тот же SQL-запрос выполняется дважды для каждого doGet ().
Почему Hibernate запрашивает базу данных при каждом вызове? Разве EntityManager не должен кэшировать объект Thing (до тех пор, пока commit () не изменит его)?
Спасибо за любую помощь!