我有一个带有数据库实体的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;
}
几年后,许多DataSet分组在一些父数据集下。
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)如何调试缓存中发生的事情?它会驱逐父母吗?还是所有的孩子?正如文章中所解释的那样,它可能会重新加载整个集合。
答案 0 :(得分:0)
您可以更改缓存使用情况=&#34;读写&#34;缓存使用情况=&#34;只读&#34;然后在代码中维护驱逐策略。这是管理缓存的最安全的方法,但需要相当多的代码来管理缓存。
有关调试的方法有两种。