a different object with the same identifier value was already associated with the session: 的解决
在做项目的时候也遇到这个问题org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:,但当是我没有解决,就用了一个最笨的办法,自己写HQL,是没问题了,今天到网上查看的时候看到了一篇好文章,不过我现在还没有试过,先暂时转过来再说.
今天做WOSS项目的时候修改那一模块突然给我抛了个org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.briup.dao.bean.Product#1008] 一看一头2个大 ,这什么破异常 ,从没遇到过嘛
遇到该异常感觉无从下手
从字面上的意思来看是2个不同的对象关联到了同一个标志位,也就是说在一个session中存在2个对象但这
2个对象的标志位是相同的比如2个对象的 id值是一样的 而这又是数据库的唯一主键
在做更新操作的时候就出现冲突了,因为Hibernate不知道到底要去更新哪个对象
出现这样的问题头都大了,后来 仔细分析了下,做前面模块的时候测试是通过了的,那为什么后面就不行了呢?
没办法只好将原来的版本拿过来重新部署测试,发现在页面提交修改数据后台做保存的时候不在抛这个异常了
将数据库发生变化导致异常的情况排出,唯一的可能就是前面做的代码被修改过,所以导致后面在去回归测试的时候
出现异常,通过比较2个版本更新模块的不 同之处后发现问题暴露出来了
DAO层方法
/**
* 修改品牌
*
* @param product
* 需要修改的品牌
* @return void
*/
public void modifyProduct(Product product) throws Exception {
session = HibernateSessionFactory.getSession();
session.update(product);
}
/**
* 通过品牌名查询品牌
*
* @author xiao_jiang51
* @param name
* @return Product
* @version1.0
*/
public Product findProductByName(String name) throws Exception {
session = HibernateSessionFactory.getSession();
query = session.createQuery("from Product where name='" + name + "'");
return (Product) query.uniqueResult();
}
看下面的业务逻辑方法
/**
* 更新品牌信息
*旧版本版本
* @param product
* 需要修改的品牌
* @return void
*/
public void modifyProduct(Product product) throws AdminServiceException {
HibernateTransaction tran = new HibernateTransaction();
tran.beginTransaction();
try {
dao.modifyProduct(product);
tran.commit();
} catch (Exception e) {
tran.rollback();
e.printStackTrace();
throw new AdminServiceException(
FinalErrorMsg.DATA_BASE_UPDATE_ERROR);
}
}
/**
* 更新品牌信息
* 新版本
* @param product
* 需要修改的品牌
* @return void
*/
public void modifyProduct(Product product) throws AdminServiceException {
Product pro = null;
pro = findProductByName(product.getName());
if (pro == null) {
throw new AdminServiceException(
FinalErrorMsg.MODIFY_PRODUCT_FAIL_BECAUSE_NOT_EXISTED);
}
HibernateTransaction tran = new HibernateTransaction();
tran.beginTransaction();
try {
dao.modifyProduct(product);
tran.commit();
} catch (Exception e) {
tran.rollback();
e.printStackTrace();
throw new AdminServiceException(
FinalErrorMsg.DATA_BASE_UPDATE_ERROR);
}
}
当Struts框架在调业务逻辑方法修改页面传过来的时候数据的时候 会去调modifyProduct方法进行修改
在新版本中就有个非常隐蔽的错误了,注意看在同一个业务逻辑方法中调了2次DAO层的方法,如果要修改的对象在
数据库中还存在就有个问题产生了,该方法获得的session管理了一个名为pro的对象而这个对象的id和方法传入的
product的id是一样的所以 当在本方法中再去调DAO层的modifyProduct方法的时候获得的session是和调
findProductByName这个业务方法获得的一个session是同一个 ,因为我把session的关闭操作放到页面请求
处理结束response回去的时候通过那个字符编码转化的filter过滤的是执行完doFilter方法后做的关闭
Hibernate Session操作来实现提交数据到数据库的 所以最终在这个修改的业务逻辑中使用2次Dao层的方法
而获得的是同一个session 所以要修改一个和该session管理的一个对象一样的identifier的对象会出现冲突.
解决办法有在该方法中执行dao.modifyProduct(product);前先将session关闭 调用Session的 close方法
Session的缓存被清空,其中的所有持久化对象都变为游离对象,
调用Session的evict()方法能够从缓存中删除一个持久化对象,使其变为游离状态,这样也能达到解决同一个
session中关联2个同一个identifer的对象更新的时候产生的冲突
问题原因找到解决就好办了,只要把要考虑并发情况出现的用户要修改的数据可能在提交后是否还存在的数据验证放到struts调用该方法的Action中去判断 就行了
从设计思想上看 修改的业务逻辑方法 还是做了它不该做的事就是去判断被修改的对象是否还存在,这个应该交给调用它的上层逻辑去判断
还有看来还是要老实的做单元测试,写好某层的某方法就先做单元测试免得让错误影响到后面的实现,最终导致一时半会找不到错误的源头
来自:http://blog.csdn.net/xiao_jiang51/archive/2007/06/05/1639794.aspx
分享到:
相关推荐
a different object with the same identifier value was already associated with the session 是一种常见的异常,通常是由于在 Hibernate 中同一个 session 里面有了两个相同标识但是是不同实体所致。解决方案有...
5. `a different object with the same identifier value was already associated with the session` 这个异常表明在同一个Hibernate Session中存在两个具有相同标识但实际是不同对象的情况。处理方法有: - 使用`...
数字对象标识符(Digital Object Identifier,简称DOI)是一种持久性标识符,用于唯一地标识数字资源,如学术文章、数据集等。DOI系统由国际DOI基金会管理,并在出版界广泛采用。随着数字资源的增加以及对资源描述的...
In these systems, packets are transmitted over the same wireless infrastructure used for cellular telephony, with the base station thus being managed by a telecommunications provider. This provides ...
- FIX: The value of some string flex-properties that began with a parenthese or curly bracket had no apostrophe at the end; that caused an error when reading. (fixed TPropList.SavePropValue for the ...
Each index row in node pages contains an index key (or set of keys for a composite index) and a pointer to a page at the next level for which the first key value is the same as the key value in the ...
- The driver can now be registered as a service with the local system account as the log-on account. For more information see the document "S7A_as_Service.PDF" on the installation CD . - The ...
When the SID is found in a value it is replaced with the new computer SID, and when the SID is found in a name, the key and its subkeys are copied to a new subkey that has the same name except with ...
Another type of table lock is a schema stability lock (Sch-S) and is compatible with all table locks except the schema modification lock (Sch-M). The schema modification lock (Sch-M) is incompatible ...
two and must be the same length on both ends.Term ID: A unique identifier for a Term within a Stream. Starts randomly. Must increase monotonically. Can wrap around. Can not go back to a wrapped ...
Adds a response header with the given name and value. addIntHeader(String, int) - Method in class javax.servlet.http.HttpServletResponseWrapper The default behavior of this method is to call ...
EXIF Data and the Map Object The speed Property Conclusion Chapter 11 : Microphone and Audio The Microphone Audio Assets Working with Sounds ID3 Tags Modifying Sound Raw Data and the Sound Spectrum ...
created with the default settings in Microsoft Visual C++ 6 with one major exception: aside from other compiler and linker flags, the executable in the DEBUG directory has been compiled with the ...
The "Identifier Case Sensitive" check box, which enables case-sensitive processing of database object identifier names, is added to MySQL Server Options The documentation generation for Enum members ...
This was due to a problem where it would be freed automatically if there was a problem with the ArchiveStream when trying to open it as a zip file (possibly corrupt). Best practice is that ...
Value: The fully-qualified identifier for the control. /// /// ///Occurs on the client side after the control has been initialized but prior to it being displayed within the browser. /// };
ASN.1 DER for SEQUENCE, INTEGER, BIT STRING, OCTET STRING, OBJECT IDENTIFIER, IA5 STRING, PRINTABLE STRING, UTCTIME, CHOICE and NULL types. Portable code builds out of the box with a conforming C ...
ProcessName is the name of the process (with or without file name extension), not a pattern. If the value of ProcessName does not match any running process, TList displays -1. If it matches more ...
在本教程中,我们将深入探讨Hibernate框架中的一个核心概念——对象标识符(Object Identifier)。通过本篇教程的学习,您将了解到对象标识符在Hibernate中的重要性以及如何正确地为持久化对象设置标识符。此外,我们...