- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
几天以来,我在使用 @Transactional 注释的 Spring 上下文中使用 Hibernate 缓存时被阻止了。
我尝试了网上找到的所有解决方案,但没有成功......
唯一可行的解决方案是使用 @Cacheable Spring 注释(来自 spring-context-support),但我不满意,因为我无法在我的实体上使用 Hibernate @Cache 注释。@Cacheable 只能用于服务方法等方法,并且我检索没有方法的实体...
例如:
我调用以下服务来获取 CollectionEntity
@Override
@Transactional(readOnly = true)
public CollectionEntity getById(Integer collectionId) throws Exception {
if(collectionId < 1) {
logger.debug("Cannot retrieve a collection from identifier inferior to 1.");
return null;
}
return collectionDao.getById(collectionId);
}
CollectionEntity 包含 ProgramEntity 集
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = CollectionProgram.TABLE, joinColumns = { @JoinColumn(name = COLUMN_COLLECTION_ID, referencedColumnName = CollectionProgram.COLUMN_COLLECTION_ID) }, inverseJoinColumns = { @JoinColumn(name = CollectionProgram.COLUMN_PROGRAM_ID, referencedColumnName = ProgramEntity.COLUMN_PROGRAM_ID) })
private Set<ProgramEntity> programs = new HashSet<ProgramEntity>(0);
这些节目包含一个 ProgramBroadcasting 集
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = ProgramBroadcastingEntity.COLUMN_PROGRAM_ID)
private Set<ProgramBroadcastingEntity> broadcastings = new HashSet<ProgramBroadcastingEntity>(0);
而这些节目广播中包含一个ChannelEntity(一个引用数据)
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = COLUMN_CHANNEL_ID, nullable = false)
private ChannelEntity channel;
因此,如果我想缓存 ChannelEntity,通常只需在其类上添加以下注释即可。
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "Channel")
@Table(name = ChannelEntity.TABLE)
public class ChannelEntity implements java.io.Serializable {
“EAGER”获取对于引用数据来说是一个非常有吸引力的解决方案!但是,如果想使用 @Cacheable(这是目前唯一的解决方案),我必须使用 FetchType.LAZY 声明 ChannelEntity 并编写一个服务类来将 @Cacheable 放在其上,以缓存此数据。这是一个笑话...我不会对所有引用数据类都这样做...
真正的解决方案就是在 ChannelEntity 上添加一个有效的 Hibernate @Cache 注释。
为了使其正常工作,我什至开发了自己的“SingletonEhCacheRegionFactory”类,使用 Spring 类“EhCacheManagerFactoryBean”作为缓存管理器进行初始化。并且继续从数据库中获取数据。该解决方案适用于我的一位同事,但适用于旧版本的 Spring (<4) 和 Hibernate (<4)。所以,对于新版本来说,这似乎不是一个好的解决方案......
所以,我真的需要你的帮助。
在向您提供我的配置之前,这里是我对主类的快速测试,用于从数据库然后从缓存检索 ChannelEntity。
这里测试正常(有效):
private static void testGetChannelFromCache2(BeanFactory factory) throws Exception {
SessionFactoryImpl sessionFactoryImpl = ((SessionFactoryImpl) factory.getBean("sessionFactory"));
Session session = sessionFactoryImpl.openSession();
session.beginTransaction();
ChannelEntity channel1 = (ChannelEntity) session.load(ChannelEntity.class, new Integer(1));
System.out.println(channel1.getLabel());
session.getTransaction().commit();
session.close();
Session anotherSession = sessionFactoryImpl.openSession();
anotherSession.beginTransaction();
// Here I put a breakpoint and I update the value directly on database.
channel1 = (ChannelEntity) anotherSession.load(ChannelEntity.class, new Integer(1));
System.out.println(channel1.getLabel()); // Here I print the cached value, not the new database value. Good!
anotherSession.getTransaction().commit();
anotherSession.close();
}
但这不是真实的上下文。在我的服务层上,我不直接操作事务,我使用了 @Transactional Spring 注释。这是一个更实际的测试:
private static void testGetChannelFromCache1(BeanFactory factory) throws Exception {
ChannelService service = (ChannelService) factory.getBean("channelServiceImpl");
ChannelEntity entity1 = service.getChannelByCode(ChannelCode.ARTE);
if(entity1 != null) {
System.out.println(entity1.getLabel());
}
// Here I put a breakpoint and I update the value directly on database.
ChannelEntity entity2 = service.getChannelByCode(ChannelCode.ARTE);
if(entity2 != null) {
System.out.println(entity2.getLabel()); // Here I print the new database value, not the cached value. Not good...
}
}
这是 ChannelService:
@Service
@Transactional(rollbackFor = Exception.class)
public class ChannelServiceImpl implements ChannelService {
@Log
private Logger logger;
@Inject
private ChannelDao channelDao;
@Override
@Transactional(readOnly = true)
public ChannelEntity getChannelByCode(final ChannelCode code) throws Exception {
if(code == null) {
logger.debug("Cannot find Channel from null code.");
return null;
}
return channelDao.getByCode(code);
}
}
现在,我的配置...
依赖关系:
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<!-- Ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
</dependency>
hibernate 配置:
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
hibernate.cache.generate_statistics=true
net.sf.ehcache.configurationResourceName=/config/ehcache/ehcache.xml
EHCache配置:
<cache name="Channel"
maxEntriesLocalHeap="10000"
eternal="true"
overflowToDisk="false">
我使用 Spring 4.0.3.RELEASE、Hibernate 4.3.4.Final 和 EHCache 2.6.8。
更准确地说,@Cache Hibernate 注释似乎有效,但不完全有效......事实上,我在 Hibernate 源代码上放置了几个断点,并且我注意到 Hibernate 将 ChannelEntity 放在缓存上,并且在我第二次调用 ChannelService 后,在缓存上获取并检索 channel 实体!但是...,Hibernate 仍然执行以下数据库请求并检索数据库值。真的很奇怪!
从 Channel this_ 中选择 this_.ChannelId 作为 ChannelI1_3_0_、this_.Code 作为 Code2_3_0_、this_.Label 作为 Label3_3_0_,其中 this_.Code=?
有人对这种奇怪的行为有任何想法吗?
非常感谢您的帮助!
最佳答案
二级缓存和查询缓存有一些问题,看起来很奇怪,但实际上很正常。
例如实体上的@Cache
将仅缓存通过其ID加载的实体。如果要缓存除按Id加载之外的查询结果,则需要将查询标记为可缓存:
@NamedQuery(name="account.queryName",
query="select acct from Account ...",
hints={
@QueryHint(name="org.hibernate.cacheable",
value="true")
}
})
或者在条件查询的情况下:
List cats = session.createCriteria(Cat.class)
.setCacheable(true)
.list();
默认情况下,一对多关系不会被缓存。如果你想缓存关联,你需要用@Cache
单独标记它们。例如:
@Cache(CacheConcurrencyStrategy.READ_WRITE)
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<ProgramEntity> programs = new HashSet<ProgramEntity>(0);
关于java - 使用 Spring 4 @Transactional + Hibernate 4 + EHCache 忽略缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23174107/
对于 Lucene,我们有一个很好的工具箱,如 Luke查看、诊断、编辑等。我们是否有类似的工具(至少显示)用于 EhCache(当我们启用 diskPersistent 时)? 最佳答案 我不知道有
我必须集成 spring 和 ehcache,并尝试使用 来实现它阻塞缓存 图案 有一个选项自填充缓存范围 对于 共享(默认)和方法 .你能解释一下有什么区别吗? 还有注解 @可缓存与 自我填充 旗
我有一个配置为使用 JPA 和 Hibernate 的大型 Java 应用程序。据说它还被配置为对实体和查询缓存使用 ehcaching。但是,我打开了 sql 日志记录,并且没有缓存任何实体。所有实
正如您在标题中看到的那样,问题很清楚,很高兴听到您对 adv./disadv 的想法。它们之间的差异。 更新:我决定使用 Hazelcast,因为它具有分布式缓存/锁定机制等优点,并且在适应您的应用程
我知道属性“updateCheck”可以在 XML 中设置为“false”,如下所示: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs
我在不同的类中创建了两个方法,并使用 @Cacheable 注释对它们进行注释,并给出了相同的缓存名称,如下所示: class MyClass{ @Cacheable(value="inSco
我正在尝试新的 ehcache 版本,但我注意到,显然,没有搜索 API。 这是正常的还是我错过了什么?文档没有说明这一点。 最佳答案 主要原因是在缓存中搜索在到期和驱逐时具有非常奇怪的语义。由于 E
在 Ehcache 2 中,可以使用 calculateInMemorySize() 获取内存中的大小,例如: CacheManager manager = CacheManager.create()
如果我有以下配置: timeToIdleSeconds 的值是多少用于缓存 test ?它会从默认缓存继承,因此等于 120,还是会采用手册中给出的默认值,即 0(无穷大)? 最佳答案 timeT
我正在使用 ehcache 通过 hibernate 缓存实体。 查看ehcache监视器,一切似乎都工作正常(刷新将缓存计数设置为零,然后重新加载将计数放回一),但是如果我直接在数据库上更改某些值并
ehcache 是一个高度可配置的野兽,示例相当复杂,通常涉及多层接口(interface)。 有没有人遇到过最简单的例子,它只是在内存中缓存一个数字(不是分布式的,没有 XML,尽可能少的 java
net.sf.ehcache.CacheManager.ALL_CACHE_MANAGERS 是否有替代品?在 org.ehcache ehcach
使用 Ehcache 3.1,我可以知道当前存储在 ehcache 中的元素的大小以及缓存到目前为止的命中和未命中数。我认为 2.6 有 .getStatistics(),它做类似的事情,但是我在 3
我是 Spring 框架中的 ehcache v/s ehcache-core 的初学者,我的 pom.xml 使用的是 ehcache 版本 1.5.0 net.sf.ehcache ehcach
我正在运行一个使用 Ehcache 3.4.0 的网络应用程序。我有一个缓存配置,它定义了 1000 个内存中对象的简单默认值: java.lang.Object java.lang
我想找到一种在 ehCache 装饰器类中使用 Spring 依赖注入(inject)的好方法。我的 ehcache.xml 具有以下缓存配置: 我有以下装饰器实现: public cl
我想弄清楚最新版本的 Ehcache(2.7.0、2.7.1、2.7.2、2.7.4、2.7.5、2.8.0)是否真的有新版本的 ehcache-core或者如果 ehcache-core 自版本 2
我们在 WebLogic Server 10.3.4 上运行 Spring 3.0.5 Web 应用程序Solaris with Sun JVM 1.6.0_x 64bit 使用 EhCache 2.
ehcache 3.8.1 是否不再自动获取源根目录下的 ehcache.xml 文件中的配置设置? 最佳答案 是的,看起来是这样,现在需要使用 XML 文件来完成 configuringe a Ca
http://ehcache.org/generated/2.9.0/html/ehc-all/#page/Ehcache_Documentation_Set%2Fco-use_supported_t
我是一名优秀的程序员,十分优秀!