zoukankan      html  css  js  c++  java
  • a different object with the same identifier value was already associated with the session

    异常描述:在执行以下方法出现此异常:

    注:类Role 与类Function 呈多对多关联,这里是添加一个role并添加三个function

    @Test//fail
        public void add(){
            Role r = new Role();
            r.setRname("Java项目经理");
            
            
            Function f = functionService.findById(98);
            Function f1 = functionService.findById(99);
            Function f2 = functionService.findById(100);
            
            r.getFunctions().add(f);
            r.getFunctions().add(f1);
            r.getFunctions().add(f2);
            
            roleService.saveOrUpdate(r);
        }

    具体异常信息:

    org.springframework.dao.DuplicateKeyException: a different object with the same identifier value was already associated with the session: [com.chen.vo.Function#99]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.chen.vo.Function#99]
        at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:662)
        at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
        at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
        at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
        at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:737)
        at com.chen.dao.RoleDaoImpl.saveOrUpdate(RoleDaoImpl.java:52)
        at com.chen.service.RoleService.saveOrUpdate(RoleService.java:38)
        at com.chen.service.RoleService$$FastClassByCGLIB$$be28c933.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:713)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:646)
        at com.chen.service.RoleService$$EnhancerByCGLIB$$3b898394.saveOrUpdate(<generated>)
        at com.chen.test.RoleTest.add(RoleTest.java:37)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
    Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.chen.vo.Function#99]
        at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:613)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:307)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
        at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
        at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
        at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:241)
        at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:292)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:240)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
        at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:320)
        at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:266)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:243)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
        at org.hibernate.engine.Cascade.cascade(Cascade.java:154)
        at org.hibernate.engine.Cascade.cascade(Cascade.java:121)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:380)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:352)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
        at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
        at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
        at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:241)
        at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:292)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:240)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
        at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:320)
        at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:266)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:243)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
        at org.hibernate.engine.Cascade.cascade(Cascade.java:154)
        at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:479)
        at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:357)
        at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
        at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
        at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
        at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
        at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:523)
        at org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:740)
        at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
        ... 45 more

    分析:根据异常的字面信息及网上提示总结原因是在com.chen.vo.Function中定义了相同的Object,类Function代码如下:

    public class Function implements Serializable{
        private int fid;
        private String fname;
        private String namespace;
        private String actioname;
        private String method;
    //    private int parentid;
        
        private Function parent;
        private Set<Function> childs = new HashSet<Function>();
        
        private Set<Role> roles = new HashSet<Role>();
        
        //...
        
    }

    类Role的代码:

    public class Role {
        private int rid;
        private String rname;//角色名
        
        private Set<Empl> empls = new HashSet<Empl>();
        private Set<Function> functions = new HashSet<Function>();
    
        //..
    }

    从以上代码可看出在类Function与类Role中均有Set<Function>的定义,因此在添加role级联添加function时出现此异常。

    解决方法:

    采用session.merge (object o)方法,这里是hibernateTemplate.merge(object o);

    代码:

    @Test//success
        public void add2(){
            Role r = new Role();
            r.setRname("Java项目经理");
            
            
            Function f = functionService.findById(98);
            Function f1 = functionService.findById(99);
            Function f2 = functionService.findById(100);
            
            r.getFunctions().add(f);
            r.getFunctions().add(f1);
            r.getFunctions().add(f2);
            
            hibernateTemplate.merge(r);
            
        }

    具体原理现在也不多去分析了,详情参见:

    http://lcy0202.iteye.com/blog/1453868

  • 相关阅读:
    解读基础设施即代码
    在那江南烈日与阵雨中-江南100赛记
    写在2017年环汶川越野赛之前
    阿里巴巴Java开发手册评述
    一个程序员的2016年总结
    面向对象的思考过程第四版译者序
    以敏捷的方式运作一所大学
    敏捷团队中的QA由来
    Spring Batch在大型企业中的最佳实践
    Java基础 awt Button 鼠标放在按钮上背景颜色改变,鼠标离开背景颜色恢复
  • 原文地址:https://www.cnblogs.com/wql025/p/4865657.html
Copyright © 2011-2022 走看看