有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java StaleObjectStateException错误

有人能告诉我错误吗

注意:这是一个从我的真实应用程序中提取的简化测试用例。 因此,3个实体经理和 em1。getTransaction()。begin(); em1。清除(); 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。坚持不懈乐观的例外:org。冬眠StaleObjectStateException:行被另一个事务更新或删除(或未保存的值映射不正确):[WebOrganizer.classes.types.StringType#174] 在org。冬眠ejb。AbstractEntityManagerImpl。WrapTaleStateException(AbstractEntityManagerImpl.java:646) 在org。冬眠ejb。AbstractEntityManagerImpl。throwPersistenceException(AbstractEntityManagerImpl.java:600) 在org。冬眠ejb。AbstractEntityManagerImpl。合并(AbstractEntityManagerImpl.java:237) 在WebOrganizer。网状物servlets。TypeServlet。test2(TypeServlet.java:356) 在阳光下。反映NativeMethodAccessorImpl。invoke0(本机方法) 在阳光下。反映NativeMethodAccessorImpl。调用(NativeMethodAccessorImpl.java:39) 在阳光下。反映DelegatingMethodAccessorImpl。调用(DelegatingMethodAccessorImpl.java:25) 在爪哇。朗,反思一下。方法调用(Method.java:597) 在org。testng。内部的方法助手。invokeMethod(MethodHelper.java:580) 在org。testng。内部的召唤者。invokeMethod(Invoker.java:517) 在org。testng。内部的召唤者。invokeTestMethod(Invoker.java:669) 在org。testng。内部的召唤者。invokeTestMethods(Invoker.java:956) 在org。testng。内部的测试方法工人。invokeTestMethods(TestMethodWorker.java:126) 在org。testng。内部的测试方法工人。运行(TestMethodWorker.java:110) 在org。testng。测试者。runWorkers(TestRunner.java:720) 在org。testng。测试者。privateRun(TestRunner.java:590) 在org。testng。测试者。run(TestRunner.java:484) 在org。testng。SuiteRunner。运行测试(SuiteRunner.java:332) 在org。testng。SuiteRunner。按顺序运行(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。RunSuitesLocal(TestNG.java:830) 在org。testng。TestNG。运行(TestNG.java:748) 在org。testng。遥远的远程测试。运行(RemoteTestNG.java:73) 在org。testng。遥远的远程测试。main(RemoteTestNG.java:124) 在阳光下。反映NativeMethodAccessorImpl。invoke0(本机方法) 在阳光下。反映NativeMethodAccessorImpl。调用(NativeMethodAccessorImpl.java:39) 在阳光下。反映DelegatingMethodAccessorImpl。调用(DelegatingMethodAccessorImpl.java:25) 在爪哇。朗,反思一下。方法调用(Method.java:597) 在com上。intellij。rt.执行。应用阿普曼。main(AppMain.java:90)

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


共 (2) 个答案

  1. # 1 楼答案

    为什么要保存对象的中间状态?如果必须,尝试另一种方法。传递标识符,确保在get之前和flush之后立即启动事务

    记住,刷新会话比调用commit要好。因为flush实际上在数据库中执行写操作,所以不需要调用close

  2. # 2 楼答案

    我想试试这样的东西:

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

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