Jpa - Hibernate @Version错误地递增 [英] Jpa - Hibernate @Version incorrectly incremented

查看:302
本文介绍了Jpa - Hibernate @Version错误地递增的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将jpa与hibernate(3.2.7)一起用作orm实现。
我有一个实体被修改,然后合并。
我也在这个实体上有一个@EntityListeners来确保某个属性被赋值。



如果我在合并之前更改一个值,然后将该值改回在Listener内部@PreUpdate方法,设置原始值,我的版本对实体结果递增,但是在数据库版本上有先前的值。
我认为这是由于对象没有改变,所以在数据库它没有更新,但在实体上的版本是递增的,没有在刷新后恢复。



为了更好地解释,我有这个对象:

pre $ @Entity
@EntityListeners({MyListener.class})
public class MyEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long ID;

private String myValue;

@版本
私人长版;
}

以及此收听者:

 公共类myListener的{

@PreUpdate
公共无效更新前的(myEntity所UA){
ua.setMyValue( 默认) ;






$ b现在假设我有一个带有这些值的对象:(id = 1,myValue ='defalut',版本= 1)。我看了这个对象,分离,把它传递给客户,并把它找回来与myvalue的=新和执行合并操作(听众变化myvalue的以默认等反对的结果未修改到DB),同花顺和交易退出(所以承诺)。
之后,我发现版本= 2在我的对象上,但版本= 1上的数据库。



这是一个休眠错误?还是Jpa的bug?

解决方案

我会说这是一个预期的行为。根据 Hibernate手册 @PreUpdate 是在数据库更新操作之前执行。因此,Hibernate已经发现它必须通过运行脏检查并使其返回true来执行UPDATE。



脏检查不会发生在 @PreUpdate ,因为Hibernate不应该调用 @PreUpdate ,除非脏检查为真。



您是否想过为 @PrePersist ,而不是 @PreUpdate ?我相信这个过程已经足够早了,因为它会进行预先检查,因此具有您想要的行为。


I'm using jpa with hibernate (3.2.7) as orm implementation. I have an entity being modified and then merged. I also have an @EntityListeners on this entity to ensure some attribute being valued.

If I change a value before merge, and then change back that value in @PreUpdate method inside Listener, setting the original value, my version on entity results incremented, but on database version has previous value. I think this is due to object didn't change, so on db it's not updated, but version on entity was alredy incremented without being restored after flush.

To explain better, i have this object:

@Entity
@EntityListeners({MyListener.class})
public class MyEntity {

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO)   
    private Long id;

    private String myValue;

    @Version    
    private Long version ;
}

and this Listener:

public class MyListener {

    @PreUpdate
    public void preUpdate(MyEntity ua) { 
        ua.setMyValue("default");
    }
}

Now suppose i have on db an object with these values: (id=1, myValue='defalut', version=1). I read this object, detach, pass it to client and get it back with myValue='new' and perform a merge operation (listener change myValue to 'default' and so object result unmodified to db), flush and exit from transaction (so is committed). After that i find version=2 on my object, but version=1 on db.

Is that an hibernate bug? Or a Jpa bug?

解决方案

I would say this is an expected behavior. According to the Hibernate manual, @PreUpdate is "Executed before the database UPDATE operation.". So, Hibernate has already figured out it has to do UPDATE by running the dirty check, and having it return true.

The dirty check can't happen AFTER @PreUpdate, because Hibernate shouldn't call @PreUpdate unless the dirty check is true. And if an update is going to be run, version should be incremented.

Have you thought about using a listener for @PrePersist, instead of @PreUpdate? I believe that's early enough in the process that it would be pre-dirty check, and thus have the behavior that you want.

这篇关于Jpa - Hibernate @Version错误地递增的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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