2011-08-20 62 views
3

正如主题所示,我在Hibernate和EhCache方面遇到了一些麻烦。Hibernate和EhCache故障缓存集合

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

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

  • 测量
    • headerinformation(一比一)
    • 内容(一比一)
      • 地方(一个对一个(我需要,因为它的元数据,此元素)
        • (集与地方的实体)(一到许多懒惰)
          • 测量(收集与测量的实体)(一对米任何懒惰)
          • timedcode(采集时间码 - eintities(一个一对多的懒惰)
            • 措施(采集与测量实体)(一个一对多的懒惰)

的问题:我想获得像012查询我的所有数据。现在有两种方法来缓存结果:Querycache和2nd-level-cache。

querycache只会缓存测量实体的select,不用说这不符合我的预期。那么我希望querycache缓存所有的sql语句。有什么办法让这个工作?

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

那么,激活所有一对多集合的缓存在获取所有数据作为第一个缓存请求的情况下效果很好。但如果没有问题,我不会写这个。通过其中一个字段查询地点作为第一个缓存操作将导致缓存做它应该做的事:它缓存所请求的数据,这意味着一个测量实体(实际上在数据库中只有一个),一个标题信息,内容与地方元素和发现的地方与其子元素。查询另一个地方也很好。现在我想要获得所有元素(上面提到的查询),但我只能得到已查询过的元素。看起来,如果语句不包含选择标准,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()

任何人都可以帮助我吗?

许多许多在此先感谢和亲切的问候

回答

5

你提的问题是很难理解,所以我就解释缓存如何工作的。

您可以缓存三两件事:

  • 实体
  • 集合实体(即一对多关联)
  • 查询

实体的缓存将使用get或负载时被击中,并且通过ToOne关联从另一个实体导航到缓存实体时。只有实体的字段被缓存。不是ToMany协会。

当浏览缓存的ToMany关联时,集合的缓存将被命中。缓存仅存储集合中实体的ID。 Hibernate将尝试使用缓存的ID逐个获取集合的所有实体。为了高效,目标实体也应该位于实体缓存中。

执行缓存查询时,查询缓存将被命中。当查询返回实体实例(例如问题的两个查询)时,查询缓存仅存储查询返回的根实体的ID。它不会缓存整个结果。 Hibernate将尝试使用缓存的ID逐个获取集合的所有实体。为了高效,目标实体也应该位于实体缓存中。因此,如果要执行查询以递归方式返回其所有关联的实体,则应使查询可缓存,使ToMany关联可缓存,并使图形的每个实体都可缓存。

+0

谢谢!我最大的问题是,如果我对一个集合的元素执行一个具体的实体(例如,地方)的查询,该元素会被提取,但我不能再获取所有的地方元素。 “来自度量c”的查询最终选择了所有已被选中的元素,所以如果以前没有任何具体的查询,查询只会得到想要的结果。那么即使collection-cache已经被填充,如何获取所有实体?当缓存为空时,我可以首先获取所有实体,但这似乎很肮脏。非常感谢提前 – daluq

+0

对不起,但我不明白。 “来自测量c”的查询将返回测量的所有实例,而不管之前查询的是什么。收集缓存是否被填充是无关紧要的。缓存可以加快速度,而不会改变查询的结果。无论缓存或无缓存,无论缓存的状态如何,您都应该得到相同的结果。你想要加载什么?编辑你的问题,举一个例子,解释你想要加载的内容以及如何做。 –

+0

_“来自度量值c”的查询将返回所有的度量实例,而不管之前查询的是什么_这是正确的,但不幸的是,它不会获得与此实体相关联的所有实体,例如地点实体。这是我的问题,收集缓存充满了来自以前查询的关联。如果你首先查询所有的元素,它的工作效果非常好,但是通过编程的方式来做这件事很麻烦。如果我在place-entity中的地点集合中禁用高速缓存或高速缓存,它将非常好用。我想加载从测量到测量的整棵树。 – daluq

0

我不得不这样做

<set lazy="false" ...> 

或遍历集合,否则收集不是写在了Ehcache。

相关问题