我有一个简单的项目,我正在学习Hibernate和JPA。我已经设置并运行了项目,能够在(HSQLDB)数据库中持久化()数据,并将create()数据退出。
我在persistence.xml中启用了show_sql选项,以查看底层发生了什么。我很困惑为什么每次查询数据时都会运行SQL查询,即使没有执行其他事务/提交。
我在类的方法中使用通过Persistence.createEntityManagerFactory()创建的单个EntityManager,由我的Servlet调用。创建它时,我调用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;
}
}
我的Servlet的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_
如果我再次调用servlet,则执行相同的SQL。如果我在之后立即放置另一个相同的createQuery()块,Hibernate会报告为每个doGet()执行两次相同的SQL。
为什么Hibernate会在每次调用时查询数据库? EntityManager不应该缓存Thing对象(直到commit()更改它)?
感谢您的帮助!
答案 0 :(得分:1)
刷新模式指示何时必须将对会话中的实体所做的更改写入数据库。它与查询无关。
此外,您没有在代码中启动任何交易。
最后,即使你是,当你执行查询时,Hibernate也会执行这个查询。第二次不会触发查询的唯一调用是em.find()
和em.getReference()
。原因是