我目前正在尝试使用EJB3作为工作中重大项目的预研。我正在研究的一件事是查询缓存。
我使用JPA注释创建了一个非常简单的域模型,一个@Local业务接口和一个EJB-JAR中的@Stateless实现,在EAR中部署了一个非常简单的webapp来进行一些基本测试。 EAR部署在JBoss 5.0.1默认配置中,无需修改。这非常简单,并按预期工作。
但是,我的最新测试涉及查询缓存,我得到了一些奇怪的结果:
这让我很困惑,所以我启用了Hibernate的show_sql来查看日志。未缓存,并且在启用缓存的第一次执行时,按预期方式记录了一个SELECT。当我应该获得缓存命中时,Hibernate会为数据库表中的每一行记录一个SELECT。
这肯定会解释执行时间慢,但是有人能告诉我为什么会这样吗?
答案 0 :(得分:16)
查询缓存的工作方式是它只缓存查询返回的对象的 ID 。因此,您的初始SELECT语句可能会返回所有对象,Hibernate会将它们返回给您并记住ID。
然而,下次发出查询时,Hibernate会浏览ID列表并意识到它需要实现实际数据。所以它返回到数据库以获得其余的。并且它每行执行一次SELECT,这正是您所看到的。
现在,在您认为“此功能明显被破坏”之前,它的工作原理是查询缓存旨在与二级缓存协同工作。如果在第一次查询后对象存储在L2缓存中,那么Hibernate将在那里查找以满足每个ID请求。
我强烈建议您选择 Java Persistence with Hibernate 这本书来了解更多相关信息。第13章特别介绍了优化查询以及如何有效地使用缓存。