麻烦用Hibernate和EhCache缓存集合

时间:2011-08-20 17:54:21

标签: hibernate caching ehcache

正如主题所暗示的那样,我在使用Hibernate和EhCache时遇到了一些麻烦。

我在Resteasy应用程序中使用Hibernate和mySql和EhCache。

模型:有一些实体,一些是一对多的,一些是一对一的关系。

  • 测量
    • 标题信息(一对一)
    • 内容(一对一)
        地方(一对一(由于其元数据我需要这个元素)
        • 地方(与地方实体的集合)(一对多懒惰)
          • 衡量(用度量实体收集)(一对多懒惰)
          • timedcode(带时间码的收集 - eintities(一对多懒)
            • 衡量(用度量实体收集)(一对多懒惰)

问题:我正在尝试在createQuery("from Measuring c").list()之类的查询中获取所有数据。现在有两种方法可以缓存结果:Querycache和2nd-level-cache。

querycache只会缓存测量实体的选择,不用说这不是我期望的行为。好吧,我希望querycache缓存所有的sql语句。有没有办法让这个工作?

我已经为所有实体激活了缓存。第二级缓存将缓存元素,但不会再次击中它们(确实如此,但只有测量元素);稍后我意识到我必须缓存集合以让缓存知道哪些元素属于一起。

好吧,在将所有数据作为第一个缓存请求获取的情况下,激活所有一对多集合的缓存非常有效。但如果没有问题,我就不会写这个。通过其中一个字段查询某个地点作为第一个缓存操作将导致缓存执行它应该执行的操作:它缓存所请求的数据,这意味着一个测量实体(实际上数据库中只有一个),一个标题信息,内容使用places-element和找到的地方及其子元素。查询另一个地方也很有效。现在我想获得所有元素(上面提到的查询),但我只得到已经查询过的元素。如果语句不包含选择标准,hibernate似乎只查询缓存。缓存集合时,这似乎是一个小问题。

所以我需要的是获取查询缓存以缓存所有语句,或者如果请求已经执行了具体的查询,则检索整个集合的第二级缓存。

我还必须提到,当检索一个具体的地方(或所有元素)时,我需要获得完整的测量元素(带有其标题信息等),因为休息服务在xml和另一方的应用程序中回答需要获得一个包含所有可能节点的测量元素。

我可以想象,我的查询中有一些错误。所以这里提到了两个问题:

获取所有数据:createQuery("from Measuring c").setCacheable(true).list()

获取具体位置的数据:createQuery("from Measuring measuringElement join fetch measuringElement.content contentElement join fetch contentElement.places placesElement join fetch placesElement.places placeElement WHERE placeElement.name = '" + name +"'").setCacheable(true).list()

有人能帮助我吗?

非常感谢提前和亲切的问候

2 个答案:

答案 0 :(得分:5)

您的问题很难理解,因此我只会解释缓存的工作原理。

您可以缓存三件事:

  • 实体
  • 实体集合(即ToMany协会)
  • 查询

使用get或load时,以及通过ToOne关联从另一个实体导航到缓存实体时,将触发实体缓存。仅缓存实体的字段。不是ToMany协会。

在浏览缓存的ToMany关联时,将会遇到集合的缓存。缓存仅存储集合中实体的ID。 Hibernate将尝试使用缓存的ID逐个获取集合的所有实体。为了提高效率,目标实体也应该在实体缓存中。

执行缓存查询时将触发查询缓存。当查询返回实体实例(例如问题的两个查询)时,查询缓存仅存储查询返回的根实体的ID。它不会缓存整个结果。 Hibernate将尝试使用缓存的ID逐个获取集合的所有实体。为了提高效率,目标实体也应该在实体缓存中。

因此,如果要执行以递归方式返回具有所有关联的实体的查询,则应使查询可缓存,使ToMany关联可缓存,并使图的每个实体都可缓存。

答案 1 :(得分:0)

我不得不做

<set lazy="false" ...>

或迭代集合,否则集合不是用Ehcache编写的。