【问题标题】:save method - doesn't flush the Session after an exception occurs保存方法 - 发生异常后不刷新会话
【发布时间】:2011-07-15 00:06:55
【问题描述】:
public class SoftwareTest extends UnitTest {

    @Before
    public void setup() {
        Fixtures.deleteAll(); // will fail if comment that. why?????
    }

    @Test
    public void createSoftwareWithNullAuthor()  {

       // when author is null

       Author nullAuthor = null;

       Software software = new Software("software1", "description1", nullAuthor);
       try {
         software.save();
         fail("author should not be null");
       } catch (PersistenceException ex) {
       }

    }


    @Test
    public void createSoftwareWithOkAuthor()  {
       // when author is ok
       Author okAuthor = new Author("author1", "email1").save(); // ERROR HERE!

       Software software2 = new Software("software2", "description2", okAuthor);
       Software savedSoftware = software2.save();
       assertNotNull(savedSoftware);
       assertEquals(savedSoftware, software2); 

       assertNotNull(savedSoftware.author);
       assertEquals(okAuthor, savedSoftware.author);
    }
}

当取消注释 Fixtures.deleteAll() 行时,我们将在第二种方法中得到 en 异常 - createSoftwareWithOkAuthor()save() 作者。 为什么会这样?

org.hibernate.AssertionFailure: null id in models.Software entry (don't flush the Session after an exception occurs)
  at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:82)
  at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:190)
  at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:147)
  at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:240)
  at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
  at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
  at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)

【问题讨论】:

标签: hibernate playframework


【解决方案1】:

来自错误:

org.hibernate.AssertionFailure: null id in models.Software 条目(发生异常后不要刷新Session

我们可以看到之前发生过会话异常。抛出此org.hibernate.AssertionFailure 的点并不是发生错误的点。

即:某些东西正在抑制原始异常。

所以寻找其他可能的错误点。 save()saveOrUpdate() 可能正在尝试使用 null 字段持久化一个实体,其中,在表中,该列是 NOT NULL

在我的例子中,真正的异常发生在 try/catch {} 块内,catch 抑制了异常(没有重新抛出或警告我)。

【讨论】:

    【解决方案2】:

    问题似乎是 Hibernate 引发了异常(因此当前事务无效),但随后您尝试在该会话中继续执行更多操作。

    执行此操作的正确方法是将您正在使用的测试分成两部分,一部分用于测试空作者,另一部分用于测试有效作者。

    在生产代码(假设是控制器)上,您需要重新启动操作(关闭事务,重新启动流程)才能继续。但是考虑到 play 管理事务的方式,正常的行为是在错误发生后您只会向用户返回一条错误消息。

    【讨论】:

    • 是的。这行得通,但我也试过了。但是还有另一个问题:在 @Before setup() 方法中,我有 Fixtures.deleteAll();如果我在此处评论此行,那么我将在第二种(拆分)方法中遇到相同的错误。这里:作者 okAuthor = new Author("author1", "email1").save();
    • 我们怎样才能停止会话不失效?
    【解决方案3】:

    也许有人会重复我的错误:

    我也遇到过这个问题。就我而言,问题发生是因为我设置了column 类型integer,并尝试写入long 值。更改column 类型后,它开始工作。

    【讨论】:

    • 就我而言,我没有放置 ManyToOne 和 JoinColumn 注释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 2012-01-28
    • 2014-05-12
    • 2023-04-07
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多