我有以下类层次结构:
@Entity
@Table(name = "BaseThing")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class BaseThing implements Serializable {
@Id
@Column(name = "id", nullable = false)
private Long id;
@Basic(optional = false)
@Column(name = "name", nullable = false, length = 48)
private String name;
...
}
@Entity
@Table(name = "ConcreteThing")
public class ConcreteThing extends BaseThing {
@Column(name = "aprop", nullable = false, length = 12)
private String aProp;
...
}
@Entity
@Table(name = "AnotherConcreteThing")
public class AnotherConcreteThing extends BaseThing {
@Column(name = "anotherprop", nullable = false, length = 12)
private String anotherProp;
...
}
我尝试读取并锁定ConcreteThing实例,因此没有其他事务可以使用hibernate LockOptions.UPGRADE
读取它。
现在功能:
BaseThing thing = (BaseThing) session.get(BaseThing.class, id, LockOptions.UPGRADE);
无效 - "选择更新"语法不是由hibernate生成的 所以对那个对象没有悲观的锁定
,同时:
BaseThing entity = (BaseThing) session.get(BaseThing.class, id);
session.refresh(entity, LockOptions.UPGRADE));
正在运行 - "选择更新"为刷新操作生成语法。
refresh()和get()函数之间的差异在于get()函数使用外部左连接来选择具体对象,而refresh()使用内部连接来选择具体对象。
在悲观锁定的上下文中这些连接之间有区别吗?
谢谢!
答案 0 :(得分:0)
某些数据库不支持使用外部联接选择更新。
在我的情况下,我使用DB2版本10.5,支持。 所以问题仍然存在。
在挖掘hibernate代码之后,我发现DB2Dialect有一个返回false的函数supportsOuterJoinForUpdate()
,而假设返回true,因为BD2支持这种选择。这是一个hibernate错误。
扩展DB2Dialect并为该函数返回true,为我解决了这个问题。