java - Hibernate 使用一级或二级缓存加载所有实体

标签 java hibernate orm caching ehcache

我们有一个完整的实体表,我们需要在 hibernate session 期间加载这些实体,我知道加载所有实体的唯一方法是通过 HQL 查询:

public <T> List<T> getAllEntities(final Class<T> entityClass) {
    if (null == entityClass)
        throw new IllegalArgumentException("entityClass can't be null");

    List<T> list = castResultList(createQuery(
            "select e from " + entityClass.getSimpleName() + " e ").list());


    return list;
}

我们使用 EHcache 进行二级缓存。

问题是这在给定的事务 session 中被调用了 100 次,并且占用了总时间的相当一部分。有什么方法可以加载给定类型的所有实体(加载整个表)并仍然受益于一级 session 缓存或二级 ehcache。

我们被告知要远离查询缓存,因为它们的潜在性能损失相对于它们的 yield 而言。 * Hibernate Query Cache considered harmful

尽管我们现在正在进行性能分析,所以可能是时候尝试打开查询缓存了。

最佳答案

L1 和 L2 缓存无法帮助您解决“获取整个表”的问题。

L1 缓存装备不良,因为如果其他人插入了一些东西,它就不在那里了。 (您可能“知道”在系统的业务规则范围内没有其他人会这样做,但 Hibernate Session 却不知道。)因此您必须查看数据库才能确定。

对于 L2 缓存,自上次有人将表放入其中后,内容可能已经过期或刷新。这可能受缓存提供者的支配,甚至可能完全在外部完成,可能通过 MBean。因此,Hibernate 在任何给定时间都无法真正知道该类型的缓存中的内容是否代表了表的全部内容。同样,您必须查看数据库才能确定。

由于您对这个实体有特殊的了解(永远不会创建新的实体),因此没有实用的方法来分配 L1 或 L2 缓存,因此您需要使用 Hibernate 提供的工具来处理特殊情况有关结果集、查询缓存或自己缓存信息的业务规则级知识。

--

如果你真的想要它在 L2 缓存中,理论上你可以使表中的所有实体成为某个其他伪造实体上的集合的成员,然后启用缓存集合并在 DAO 中 secret 管理它。不过,我认为在您的代码中使用这种奇怪的东西可能不值得 :)

关于java - Hibernate 使用一级或二级缓存加载所有实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3613692/

相关文章:

java - 尝试在目录之间 move 时文件正在使用异常

java - 无法让 findAll 在 Elasticsearch 中工作

java - hibernate是否默认使用PreparedStatement

java - 从 java pojo 类生成 hibernate 查询

java - 使 JButton 拉伸(stretch)以适合 JPanel

java - Spring Security如何检索用户名

java - Spring Data JPA 与 H2 数据库 : Connect two Entities in different Projects

Django ORM 获取每行的最新版本(内连接)

c# - 使用序列化维护对象关系映射

sql - 将两个数据库表变成一个?