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个
# 1 楼答案
为什么要保存对象的中间状态?如果必须,尝试另一种方法。传递标识符,确保在
get
之前和flush
之后立即启动事务记住,刷新会话比调用commit要好。因为flush实际上在数据库中执行写操作,所以不需要调用close
# 2 楼答案
我想试试这样的东西:
在清理EntityManager之前,不确定为什么要开始交易。我不以编程方式处理JPA事务,所以这只是一个有根据的猜测。另外,如果每次都返回相同的实例,为什么还要创建一个新的EntityManager