【问题标题】:Using LocalDateTime as @Version field with Hibernate 5.3 / JPA 2.2 on Java 11 leads to StaleObjectStateException在 Java 11 上将 LocalDateTime 用作带有 Hibernate 5.3 / JPA 2.2 的 @Version 字段会导致 StaleObjectStateException
【发布时间】:2019-11-29 21:13:43
【问题描述】:

考虑一个名为Template 的实体,其中包含一个字段:

@Version
@Column(name = "LAST_UPDATE", nullable = false)
private LocalDateTime lastUpdate; // Java 8's class

支持 Oracle 数据库字段是 TIMESTAMP

现在执行以下代码:

        // get EntityManager, start transaction
        final var t = new Template();
        t.setName("new template");
        t.setSubject("subject");

        em.persist(t);
        t.setSubject("subject - mod");
        tx.commit();

导致抛出异常:

Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [Template#169]
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2525)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3357)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3231)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3632)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:146)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1453)
... 59 common frames omitted

如果我将lastUpdate 的类型更改为java.sql.Timestamp,则代码可以正常工作。可能是什么问题?

虽然文档中没有明确说明,但我认为 Hibernate 支持这种类型作为 @Version 字段。

这里有一个测试用例:https://github.com/imeszaros/jooby-hbm-localdatetime

【问题讨论】:

  • 我已经测试了你展示的代码,但是没有抛出异常。这是我用来检查您的问题的github repo。您能否检查一下我缺少的内容以及您可以展示的更多内容以帮助我们帮助您
  • @A.Henteti 我忘了提到我们正在使用 Java 11。请查看以下存储库:github.com/imeszaros/jooby-hbm-localdatetimeApp.java 中有一个用于数据库表的 SQL 脚本。只需尝试启动应用程序,它应该会导致上述异常。

标签: hibernate jpa java-time optimistic-locking staleobjectstateexception


【解决方案1】:

仅作记录:Oracle的TIMESTAMP类型默认精度为6,只能存储毫秒。

然而,Java 的 LocalDateTime 可能有纳秒,因此您需要在数据库中使用 TIMESTAMP(9) 才能在不损失精度的情况下存储值。

【讨论】:

    猜你喜欢
    • 2020-12-25
    • 2014-08-10
    • 2015-03-01
    • 2014-10-21
    • 2016-01-28
    • 2019-06-15
    • 2017-10-07
    • 2020-06-04
    • 1970-01-01
    相关资源
    最近更新 更多