我一直都知道用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?
答案 0 :(得分:2)
您正在合并PollVote并已将Hibernate配置为将合并级联到PollVote的用户。因此,hibernate会在此期间检查其合并用户的状态是否未被其他事务修改。这就是优化锁定的重点。
在合并PollVote时,您似乎真的不想合并User的状态。在这种情况下,删除cascade = MERGE属性,只需使用EntityManager.getReference()
来获取您希望PollVote附加到的用户的引用。