【问题标题】:StaleObjectStateException ERRORStaleObjectStateException 错误
【发布时间】:2009-01-10 12:19:20
【问题描述】:

谁能指出错误?

注意:这是从我的真实应用中提取的简化测试用例。 因此 3 个实体管理器的奇怪用法和 em1.getTransaction().begin(); em1.clear(); em1.close(); 在每个部分的末尾。 在真实的应用程序中,它发生在不同的时间。 HibernateUtil 基本上是从教程中抄来的。

        HibernateUtil.open();

        EntityManager em1 = HibernateUtil.reserveEntityManager();
        em1.getTransaction().begin();
        StringType st1 = new StringType();
        st1.setName("a");
        em1.persist(st1);
        em1.getTransaction().commit();
        em1.getTransaction().begin();
        em1.clear();
        em1.close();

        EntityManager em2 = HibernateUtil.reserveEntityManager();
        em2.getTransaction().begin();
        StringType st2 = new StringType();
        st2.setName("a");
        st2.setId(st1.getId());
        em2.merge(st2);
        em2.getTransaction().commit();
        em2.getTransaction().begin();
        em2.clear();
        em2.close();

        EntityManager em3 = HibernateUtil.reserveEntityManager();
        em3.getTransaction().begin();
        StringType st3 = new StringType();
        st3.setName("a");
        st3.setId(st1.getId());
        [b]em3.merge(st3);[/b]
        em3.getTransaction().commit();
        em3.getTransaction().begin();
        em3.clear();
        em3.close();



public static EntityManager reserveEntityManager()
    {
        return emf.createEntityManager();
    }

public static void open()
    {
        try
        {           
            emf = Persistence.createEntityManagerFactory("manager1");
        }
        catch (Throwable e)
        {
            throw new ExceptionInInitializerError(e);
        }
    }

javax.persistence.OptimisticLockException:org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存的值映射不正确):[WebOrganizer.classes.types.StringType#174] 在 org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:646) 在 org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:600) 在 org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:237) 在 WebOrganizer.web.servlets.TypeServlet.test2(TypeServlet.java:356) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:580) 在 org.testng.internal.Invoker.invokeMethod(Invoker.java:517) 在 org.testng.internal.Invoker.invokeTestMethod(Invoker.java:669) 在 org.testng.internal.Invoker.invokeTestMethods(Invoker.java:956) 在 org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126) 在 org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:110) 在 org.testng.TestRunner.runWorkers(TestRunner.java:720) 在 org.testng.TestRunner.privateRun(TestRunner.java:590) 在 org.testng.TestRunner.run(TestRunner.java:484) 在 org.testng.SuiteRunner.runTest(SuiteRunner.java:332) 在 org.testng.SuiteRunner.runSequentially(SuiteRunner.java:327) 在 org.testng.SuiteRunner.privateRun(SuiteRunner.java:299) 在 org.testng.SuiteRunner.run(SuiteRunner.java:204) 在 org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:864) 在 org.testng.TestNG.runSuitesLocally(TestNG.java:830) 在 org.testng.TestNG.run(TestNG.java:748) 在 org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:73) 在 org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:124) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)

原因:org.hibernate.StaleObjectStateException:行被另一个事务更新或删除(或未保存的值映射不正确):[WebOrganizer.classes.types.StringType#174] 在 org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:261) 在 org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120) 在 org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53) 在 org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677) 在 org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661) 在 org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665) 在 org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:228) ... 28 更多

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    我会尝试这样的:

    EntityTransaction tx1 = em1.getTransaction();
    // make your modifications
    em1.merge(st1);
    tx1.commit();
    

    不确定为什么要在清理 EntityManager 之前开始事务。我不以编程方式处理 JPA 事务,所以这只是一个有根据的猜测。另外,如果它返回相同的实例,为什么每次都创建一个新的 EntityManager?

    【讨论】:

      【解决方案2】:

      为什么要保存对象的中间状态?如果必须,请尝试另一种方法。传递标识符,确保您在 getflush 之后立即开始事务。

      请记住,刷新会话比调用提交更好。由于 flush 实际上是在数据库中执行写入操作,因此您无需调用 close。

      【讨论】:

        猜你喜欢
        • 2013-08-13
        • 2014-10-07
        • 1970-01-01
        • 2019-04-04
        • 1970-01-01
        • 2013-04-02
        • 2013-03-25
        • 1970-01-01
        • 2015-06-22
        相关资源
        最近更新 更多