一个Memcache+Hibernate自处理二级缓存问题
来源:互联网 发布:java 调试 class文件 编辑:程序博客网 时间:2024/06/05 08:36
背景:使用Memcache+Hibernate时,在同一个session中先做新增操作,object放入memcache中,后续操作中,再从Memcache中取出update时会报错。而当缓存使用的是Ehcache时,则不会有该问题。
报错关键信息:a different object with the same identifier value was already associated with the session
解决方法直接看本文最下面
猜想:两者缓存中的差别为Memcache需要序列化保存,而Ehcache不需要,顺着这个思路想下去:
新增,object被序列化到Memcached中,后面再取出来更新时,反序列化,id一样,但是hibernate认为这不是同一个obect。
使用ehcache时,用的是Map的方式实现,不需要序列化,所以这种方式手动管理的二级缓存不会有这样子的问题。
验证:这里的猜想完全基于Hibernate对object比较的机制,即报错中说的为什么是“a different object”,于是查看了下Hibernate的源码。
测试代码:
@Testpublic void test1() { session.beginTransaction(); User user = new User(); user.setAge(20); user.setName("zhang san"); session.save(user); //put user into memcache client.set("111", 10000, user); //get user from memcache user = (User) client.get("111"); user.setName("li si"); session.update(user); session.getTransaction().commit(); System.out.println("Over");}
报错:
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.closer.user.User#7]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:617)
at
…..
StatefulPersistenceContext.class中的代码抛出了异常,通过查看该代码,发现Hibernate判断两个实体是不是same object主要采用看两者的内存地址是否两等。(object为从memcache反序列化后的实例,entity为通过id从一级缓存中获取的实例)
源码
@Overridepublic void checkUniqueness(EntityKey key, Object object) throws HibernateException { final Object entity = getEntity( key ); if ( entity == object ) { throw new AssertionFailure( "object already associated, but no entry was found" ); } if ( entity != null ) { throw new NonUniqueObjectException( key.getIdentifier(), key.getEntityName() ); }}
而当二级缓存使用的是ehcache是,由于不需要序列的过程,因此二级缓存中的实例跟一级缓存中的实例指向的同一个内存地址。
接下来的问题就是:改由使用hibernate集成的二级缓存管理时,为何就不会有问题。所以要查看下,看Hibernate在保存时有做了什么操作(暂时没有找到hibernate-memcache的源码包,后续再看看)
解决方法:根据上面的结果,其实只要在update前,将entity从一级缓存中擦除即可解决问题
// clear L1 cache//session.evict(user);session.clear();user.setName("li si");session.update(user);
- 一个Memcache+Hibernate自处理二级缓存问题
- hibernate使用memcache做二级缓存
- hibernate 二级缓存 处理
- Hibernate二级缓存问题
- Hibernate 二级缓存 失效问题!!!
- Hibernate二级缓存问题
- Hibernate的二级缓存问题?
- Hibernate二级缓存问题
- hibernate中的二级缓存的问题
- hibernate配置二级缓存出现的问题
- hibernate 延迟加载 二级缓存 注解配置问题
- hibernate一级缓存和二级缓存的问题
- hibernate Search 继续研究 增加 hibernate memcache 二级缓存 配置成功 附件maven代码(2)
- hibernate 二级缓存
- hibernate 二级缓存
- hibernate二级缓存
- Hibernate二级缓存
- hibernate二级缓存
- 字符编码GBK与UTF-8
- StringBuffer
- Ajax异步&同步请求
- Android日记1
- Python边学边记录之2-常用的集合(列表、原组、字典)
- 一个Memcache+Hibernate自处理二级缓存问题
- git & Python教程
- Java 100个高质量Java开发者博客
- 3.3 计算字符串的相似度
- canvas绘制时的颜色与透明度
- sting转换为Unicode
- yate学习--yateclass.h--class YATE_API DebugEnabler
- ARM异常处理
- linux驱动学习(八) i2c驱动架构(史上最全) davinc dm368 i2c驱动分析