首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >StaleObjectStateException错误

StaleObjectStateException错误
EN

Stack Overflow用户
提问于 2009-01-10 12:19:21
回答 2查看 6.3K关注 0票数 3

谁能告诉我哪里出错了?

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

代码语言:javascript
复制
        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:行已被另一个事务更新或删除(或未保存的值映射不正确):位于org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:646) at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:600) at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:237) at WebOrganizer.web.servlets.TypeServlet.test2(TypeServlet.java:356) at sun.reflect的WebOrganizer.classes.types.StringType#174sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:580) at org.testng.internal.Invoker.invokeMethod(Invoker.java:517) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:669)的.NativeMethodAccessorImpl.invoke0(本机方法)在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) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:327) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:299) at org.testng.SuiteRunner.run(SuiteRunner.java:204) at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:864) at org.testng.TestNG.runSuitesLocally(TestNG.java:830) at org.testng.TestNG.run(TestNG.java:748) at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:73) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:124) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)

原因:行已被另一个事务更新或删除(或未保存的值映射不正确):位于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)的WebOrganizer.classes.types.StringType#174位于org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661) at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665) at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:228) ...还有28个

EN

回答 2

Stack Overflow用户

发布于 2009-01-10 18:33:10

我会试一试这样的东西:

代码语言:javascript
复制
EntityTransaction tx1 = em1.getTransaction();
// make your modifications
em1.merge(st1);
tx1.commit();

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

票数 1
EN

Stack Overflow用户

发布于 2011-08-29 02:17:03

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/430899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档