MyException - 我的异常网
当前位置:我的异常网» 开源软件 » 【错误】net.sf.hibernate.NonUniqueObjectExceptio

【错误】net.sf.hibernate.NonUniqueObjectException

www.MyException.Cn  网友分享于:2013-06-29  浏览:8次
【异常】net.sf.hibernate.NonUniqueObjectException

net.sf.hibernate.NonUniqueObjectException:
a different object with the same identifier value was already associated with the session: .........

今天遇到这样的报错异常,网上搜索答案,以下的代码逻辑就会出现该异常:

SessionFactory sessionFactory= new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
User user1=new User("anray");
User user2=new User("anray");

//假设User是一个持久对象,有一个name属性
user1.setName("anray1");
user2.setName("anray2");
session.update(user1);
session.update(user2);

这样的代码,我们一般不可能会这样写,但有时,我们回写一个专门的类来管理sessionFactory和session,如:
package com.cpic.p17.pf.dao;

import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

/**
 * Hibernate DAO实现
 * @author fanjf
 * @date 2012-3-22
 */
public class HibernateDao {
    private static final SessionFactory sessionFactory;
    static {
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (HibernateException ex) {
            throw new RuntimeException("Exception building SessionFactory: " + ex.getMessage(), ex);
        }
    }
   
    public static final ThreadLocal threadLocal = new ThreadLocal();
   
    /** 得到当前线程的session */
    public static final Session getSession() throws HibernateException {
        Session se = (Session) threadLocal.get();
        // Open a new Session, if this Thread has none yet
        if (se == null) {
            se = sessionFactory.openSession();
            threadLocal.set(se);
        }
        return se;
    }
   
    /** 关闭当前线程的session */
    public static final void closeSession() throws HibernateException {
        Session s = (Session) threadLocal.get();
        threadLocal.set(null);
        if (s != null)
            s.close();
    }
   
    /**
     *保存一个对象到数据库中,使用完后要自己调用closeSession()
     */
    public static void create(Object object) throws HibernateException {
        Session session1 = getSession();
        Transaction transaction1 = session1.beginTransaction();
        try {
            session1.save(object);
            transaction1.commit();
        } catch (HibernateException ex) {
            if (transaction1 != null)
                transaction1.rollback();
            closeSession();
            throw ex;
        }
    }
   
    /**
     *更新一个对象到数据库中,使用完后要自己调用closeSession()
     */
    public static void update(Object object) throws HibernateException {
        Session session1 = getSession();
        Transaction transaction1 = session1.beginTransaction();
        try {
            session1.update(object);
            transaction1.commit();
        } catch (HibernateException ex) {
            if (transaction1 != null)
                transaction1.rollback();
            closeSession();
            throw ex;
        }
    }
}

如果在web编程时用这个类的方法来更新一个user对象,在调用了HibernateUse.update(user)后,没有接着调用HibernateUse.closeSession(),其实为了节省资源也不提倡每次操作都调用HibernateUse.closeSession()关闭session;如果对相同的user对象进行又一次的更新时,碰巧容器又分配了同一个thread进行处理,那么得到的也是同一个session,这样就出现了上面的提到了问题,session里的两个user的识别id一样,但内容不一样。

为了解决这个问题可以在update前清空session(不是关闭,这样资源消耗比较少),修改后的公用类如下:
(就是在update()方法里添加了session1.clear();)
    /**
     *更新一个对象到数据库中,使用完后要自己调用closeSession()
     */
    public static void update(Object object) throws HibernateException {
        Session session1 = getSession();
        Transaction transaction1 = session1.beginTransaction();
        try {
            session1.clear();//更新对象前,清空session

            session1.update(object);
            transaction1.commit();
        } catch (HibernateException ex) {
            if (transaction1 != null)
                transaction1.rollback();
            closeSession();
            throw ex;
        }
    }

文章评论

鲜为人知的编程真相
鲜为人知的编程真相
中美印日四国程序员比较
中美印日四国程序员比较
代码女神横空出世
代码女神横空出世
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
那些争议最大的编程观点
那些争议最大的编程观点
漫画:程序员的工作
漫画:程序员的工作
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
旅行,写作,编程
旅行,写作,编程
总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员必看的十大电影
程序员必看的十大电影
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
我是如何打败拖延症的
我是如何打败拖延症的
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
老程序员的下场
老程序员的下场
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
每天工作4小时的程序员
每天工作4小时的程序员
编程语言是女人
编程语言是女人
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
 程序员的样子
程序员的样子
Java程序员必看电影
Java程序员必看电影
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序员应该关注的一些事儿
程序员应该关注的一些事儿
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
我的丈夫是个程序员
我的丈夫是个程序员
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员和编码员之间的区别
程序员和编码员之间的区别
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
一个程序员的时间管理
一个程序员的时间管理
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员都该阅读的书
程序员都该阅读的书
如何成为一名黑客
如何成为一名黑客
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有