使用cascade = CascadeType.MERGE + @Version = Staleobjectexception重新附加已分离的对象

时间:2013-07-31 20:00:22

标签: hibernate jpa

我一直都知道用cascade = CascadeType.MERGE标记一个方法会导致重新附加任何分离的实体,这可能涉及到数据库的往返

public class PollVote{
@ManyToOne(cascade=CascadeType.MERGE,fetch=FetchType.LAZY,optional=true)
@JoinColumn(name="FK_UserId",nullable=true,updatable=false)
public User getUser() {
    return user;
}

在这种情况下,User类具有@Version属性

public class User{
@Column
@Version
@JsonIgnore
public Date getLastUpdate() {
    return lastUpdate;
}

但是,在某些情况下,我收到了StaleObjectStateException。我意识到这一定必须发生,因为我传递的用户对象只是从会话中获取,因此它可能是陈旧的。在这种情况下,这在很大程度上是无关紧要的,因为所需要的只是保存pollVote的用户对象的id。

我的第一个问题是:在cascade = CascadeType.MERGE:如果你传入一个带有@Version属性的陈旧对象,那么Hibernate不应该从数据库刷新对象而不是抛出staleobjectstateexception?

我的第二个问题是:为什么在需要的所有内容都是不可变的id时抛出StaleObjectStateException?

1 个答案:

答案 0 :(得分:2)

您正在合并PollVote并已将Hibernate配置为将合并级联到PollVote的用户。因此,hibernate会在此期间检查其合并用户的状态是否未被其他事务修改。这就是优化锁定的重点。

在合并PollVote时,您似乎真的不想合并User的状态。在这种情况下,删除cascade = MERGE属性,只需使用EntityManager.getReference()来获取您希望PollVote附加到的用户的引用。