1

我有以下类层次结构:

@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;

    ...
}

我正在尝试使用 hibernate 读取并锁定一个 ConcreteThing 实例,以便没有其他事务可以读取它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() 使用内连接来选择具体对象。

在悲观锁定的上下文中,这些连接之间有区别吗?

谢谢!

4

1 回答 1

1

一些数据库不支持使用外连接选择更新。

在我的情况下,我使用支持的 DB2 版本 10.5。所以问题仍然存在。

在挖掘休眠代码后,我发现 DB2Dialect 有一个supportsOuterJoinForUpdate()返回 false 的函数,而假设返回 true,因为 BD2 支持这种选择。这是一个休眠错误。扩展 DB2Dialect 并为该函数返回 true,为我解决了这个问题。

于 2015-07-14T07:42:38.173 回答