Hibernate悲观锁定不适用于多态查询

时间:2015-07-01 16:13:59

标签: hibernate locking pessimistic-locking

我有以下类层次结构:

@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()使用内部连接来选择具体对象。

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

谢谢!

1 个答案:

答案 0 :(得分:0)

某些数据库不支持使用外部联接选择更新。

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

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