我正在尝试将项目代码从OSCache迁移到EhCache。
我们不仅将OSCache用作二级Hibernate缓存提供程序,而且还用于存储其他性质不同的对象。他们都很高兴地共享同一个缓存实例,而不会由于不重叠的缓存键而发生任何冲突。
迈向EhCache的一大区别是每个区域都有其不同的缓存实例。这可能很好,因为它可以提高查找速度,因为不同性质的数据分别存在。不幸的是,这要付出惨重的代价。让我解释。
在OSCache世界中,我将缓存容量配置为10000。现在,如果特定的安装需要/可以提供更多的RAM,我很容易将其增加到50000,那样就可以了。现在在EhCache中,我必须针对每个区域按此增量的一部分更改设置!
此外,一个安装可能会更频繁地使用X类型的对象,而另一个安装可能会更喜欢使用Y类型的对象。我们有数十个安装,每个安装都会有数百个不同的缓存。为此,我们将不得不雇用一群人,除了监视缓存模式和调整设置外,什么也不做!
我期望CacheManager具有某种全局缓存容量设置,并且每个内部缓存都将争取更多容量,具体取决于条目的使用情况。但是我发现,设置缓存容量的唯一方法是通过CacheConfiguration这是许多到一对CacheManager。
CacheManager
CacheConfiguration
到目前为止,我只能看到的唯一选择是尝试强制Hibernate对所有实体使用一个全局缓存。有人知道该怎么做吗?我的方案还有其他更好的解决方案吗?
您可以尝试使用一个缓存并在其周围添加装饰器。装饰器的名称可以与您的区域名称匹配,以便hibernate可以使用这些缓存,但是这些装饰器将在下面使用相同的缓存。因此,只有一个缓存配置可以管理。您可以通过实现自定义缓存装饰器并设置装饰的缓存的名称来实现。
您可以拥有ehcache.xml这样的内容:
<defaultCache maxElementsInMemory="10000" eternal="false" overflowToDisk="false"/> <cache name="singleSharedCache" maxElementsInMemory="2000" eternal="false" overflowToDisk="false"> <cacheDecoratorFactory class="com.xyz.util.CustomEhcacheDecoratorFactory" properties="name=org.hibernate.tutorial.domain.Person" /> <cacheDecoratorFactory class="com.xyz.util.CustomEhcacheDecoratorFactory" properties="name=org.hibernate.tutorial.domain.Event" /> </cache>
“ com.xyz.util.CustomEhcacheDecoratorFactory”是一个自定义ehcache装饰器工厂类,用于创建装饰后的ehcache。您可以使用“ properties”属性以所需的任何方式设置修饰的ehcache,在这里,您仅使用name属性来配置新修饰的ehcache的名称。可以将所有其他操作委托给基础缓存。
提供了一个适用于此用例的自定义缓存装饰器,它重用了ehcache jar中附带的EhcacheDecoratorAdapter,并且仅覆盖了getName()。EhcacheDecoratorAdapter将所有操作委托给您在构造函数中传递的基础ehcache:
包com.xyz.util; 导入java.util.Properties; 导入net.sf.ehcache.Ehcache; 导入net.sf.ehcache.constructs.CacheDecoratorFactory; 导入net.sf.ehcache.constructs.EhcacheDecoratorAdapter; 公共类CustomEhcacheDecoratorFactory扩展了CacheDecoratorFactory { 公共Ehcache createDecoratedEhcache(最终Ehcache缓存, 最终属性属性){ 返回新的EhcacheDecoratorAdapter(cache){ 私有最终字符串名称= properties.getProperty(“ name”); 公共字符串getName(){ 返回名称; } }; } 公共Ehcache createDefaultDecoratedEhcache(最终Ehcache缓存, 最终属性属性){ 返回新的EhcacheDecoratorAdapter(cache){ 私有最终字符串名称= properties.getProperty(“ name”); 公共字符串getName(){ 返回名称; } }; } }