我有一个Java/Spring应用程序与数据库实体。 其中一个实体是DataSet
。每个DataSet可以有一个父节点DataSet
。 并且父母 - DataSet
有多个(OneToMany)子女。休眠集合缓存
@OneToMany(fetch=FetchType.LAZY)
@IndexColumn(name = "order_id")
@JoinColumn(name = "parent_dst_id")
@Fetch(FetchMode.SELECT)
@Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
public List<DataSet> getChildren()
{
return children;
}
经过几年很多在某些父数据集进行分组的数据集。
parentDataset.getChildren().size() // > 200.000
在代码(我不知道这是正确的方式)增加一个新的数据集(调查)与母体时,以下行执行:
surveyDataset.setParent(parentDataset);
parentDataset.getChildren().add(surveyDataset);
直到最近children
根本没有被缓存。第二条语句导致数据库中的长时间运行查询。
现在我们最近添加了datasets.children
到缓存。这样,一切都变得非常快。
直到...
..一个孩子,数据集添加(同一母公司下进行!)再次变得很慢(即:它开始再次查询该数据库)。
我认为缓存正在被驱逐或清除或者其他什么,这就是再次查询的原因。
参见:http://planet.jboss.org/post/collection_caching_in_the_hibernate_second_level_cache(TLDR: “Hibernate并不在缓存更新集合,它只是删除它。”)
我试图理解日志(net.sf.ehcache = DEBUG和org.hibernate.SQL = DEBUG)但那很困难。
所以我只能和我有什么做的,以防止再次加载所有儿童的数据集(在新数据集中的所有兄弟姐妹)有几个问题
1)? 2)如何调试我的缓存中发生了什么?它驱逐父母吗?还是所有的孩子?正如文章中所解释的那样,它可能会重新加载整个集合。
谢谢! “维持驱逐政策”究竟意味着什么? – codesmith
当你把缓存用法=“读写”时,hibernate处理对象驱逐。只要使用session.save/update更新任何对象,它就会从缓存中逐出缓存的对象。但是Read不允许hibernate这样做,所以你将不得不以编程方式在代码中写入缓存逐出来处理它。 – user1622369