代码之家  ›  专栏  ›  技术社区  ›  Freiheit

eclipseLink jpa`@preupdate`调用不持久

  •  8
  • Freiheit  · 技术社区  · 15 年前

    我在StackOverflow上遇到了一些类似的问题,尝试了解决方案,但没有找到答案。

    我使用一个相当常见的JPA策略来设置一些实体的最后修改时间。设置列和字段,然后用 @PreUpdate 让它设置它们等于当前时间。

    问题是,我可以在调试器中看到正在调用该方法并且正在更新该字段,但是在我的数据库日志中,我只看到一个SQL调用,用于更新不包含时间戳字段更新的已更改字段。

    使事情更加复杂化 @PrePersist 仅适用于 @预更新 排除这种行为。

    到目前为止,我找到的最贴切的解释是 LINK .

    类似问题见:1725699和1745890

    我使用EclipseLink v2和JPA v1与GlassFish v2兼容。

    我尝试直接在实体类的方法上使用这两个注释,以及 EntityListener 附加到实体类 @EntityListener 注释。

    我怀疑这是EclipseLink中的一个bug,但我无法证明。

    不管有没有bug,我都非常喜欢这个简单的操作。这个实现有什么问题吗?这是EclipseLink中的已知问题吗?这是JPA中的已知问题吗?有办法解决这个问题吗?

    除了进入数据库和使用触发器,还有一个替代的路径让我的Java代码设置更新的时间戳吗?

    谢谢你的建议!

    下面是代码段。

    实体字段:

    @Column(name = "updated_on")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedOn;
    @Column(name = "created_on")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdOn;
    

    带注释的更新方法:

    @PreUpdate
    public void setUpdatedOn(Timestamped object) {
        object.setUpdatedOn(new Date());
    }
    
    @PrePersist
    public void setCreatedOn(Timestamped object) {
        if (object.getCreatedOn()==null) {
          object.setCreatedOn(new Date());
        }
    }
    
    2 回复  |  直到 9 年前
        1
  •  6
  •   FelixM    15 年前

    您提供的链接正好描述了您的情况:对于脏检查,在调用@preupdate方法之前检测到更新的字段,并且不再检测到@preupdate方法中的更改。这可能是因为性能原因,因为脏检查在大型对象图上可能非常昂贵。现在您的选择似乎是使用特定于提供程序的机制(DescriptorEvent)或切换到Hibernate。

        2
  •  5
  •   Michele Mariotti    10 年前

    我有点晚了,但为了信息的完整性,这不是一个错误,而是一个记录在案的行为:

    假定日期或日历类型 不是 要在默认情况下可变,如果希望在日期或日历上调用set方法,则映射必须设置为@mutable。

    对于日期和日历类型,全局持久性属性“eclipseLink.temporal.mutable”也可以设置为“true”。

    所以,要么注释

    @Mutable
    @Column(name = "updated_on")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedOn;
    

    或定义

    <property name="eclipselink.temporal.mutable" value="true" />
    

    在persistence.xml中