EclipseLink JPA` @ PreUpdate`调用不会持久化 [英] EclipseLink JPA `@PreUpdate` call not persisting

查看:137
本文介绍了EclipseLink JPA` @ PreUpdate`调用不会持久化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我使用相当常见的JPA策略来设置某些实体的最后修改时间。设置列和字段,然后使用 @PreUpdate 标记方法,并将它们设置为等于当前时间。



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



进一步复杂化的事情 @PrePersist 运作正常,只有 @PreUpdate 表示这种行为。



到目前为止,我发现的最接近的解释是 LINK



类似问题:#1725699和#1745890



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



<我试图直接在Entity cl中的方法上使用两个注释使用 @EntityListener 注释附加到Entity类的 EntityListener



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



错误与否我非常希望这个简单的操作能够工作。这个实现有什么问题吗?这是EclipseLink中的已知问题吗?这是JPA中的已知问题吗?有没有解决的办法?



如果没有进入数据库并使用触发器,是否有另一条路径让我的Java代码设置updated_on时间戳?



感谢您的建议!



以下是代码片段。



实体字段:

  @Column(name =updated_on)
@Temporal(TemporalType.TIMESTAMP)
private Date updatednn;
@Column(name =created_on)
@Temporal(TemporalType.TIMESTAMP)
private Date creatednn;

带注释的更新方法:

  @PreUpdate 
public void setUpdatedOn(Timestamped object){
object.setUpdatedOn(new Date());
}

@PrePersist
public void setCreatedOn(Timestamped object){
if(object.getCreatedOn()== null){
object.setCreatedOn (新日期());
}
}


解决方案

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


I ran into some similar questions on StackOverflow, tried the solutions, but did not find an answer.

I am using a fairly common JPA strategy to set last modified times on some entities. Set up the columns and the fields, then tag a method with @PreUpdate and let it set them equal to the current time.

The problem is that I can see in the debugger that the method is being called and that the field is being updated, however in my DB logs I only see a SQL call to UPDATE the changed field that does NOT include an UPDATE for the timestamp field.

Complicating things further @PrePersist works perfectly, only @PreUpdate exibits this behaviour.

The closest explanation I've found so far is at this LINK.

Similar questions at: #1725699 and #1745890

I am using EclipseLink v2 and JPA v1 for compatibility with GlassFish v2.

I have attempted using both annotations directly on methods in the Entity class as well as an EntityListener attached to the Entity class with the @EntityListener annotation.

I suspect this is a bug in EclipseLink, but I can't prove it.

Bug or not I would very much like this simple operation to work. Is there anything wrong with this implementation? Is this a known issue in EclipseLink? Is this a known issue in JPA? Is there a way around this?

Short of going to the database and using triggers, is there an alternate path to let my Java code set the updated_on timestamp?

Thanks for the advice!

Code snippets follow.

Entity fields:

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

Annotated update methods:

@PreUpdate
public void setUpdatedOn(Timestamped object) {
    object.setUpdatedOn(new Date());
}

@PrePersist
public void setCreatedOn(Timestamped object) {
    if (object.getCreatedOn()==null) {
      object.setCreatedOn(new Date());
    }
}

解决方案

The link you provide describes exactly your situation: for the dirty check, updated fields are detected before the @PreUpdate method is called and changes in the @PreUpdate method are not detected any more. This is probably done for performance reasons because dirty checks can be very expensive on large object graphs. It seems right now your choices are to use a provider-specific mechanism (DescriptorEvent) or to switch to Hibernate.

这篇关于EclipseLink JPA` @ PreUpdate`调用不会持久化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆