【问题标题】:Hibernate - apply locks to parent tables in polymorphic queriesHibernate - 在多态查询中对父表应用锁
【发布时间】:2009-11-24 01:22:55
【问题描述】:

我有两个对象:

public class ParentObject {
 // some basic bean info
}

public class ChildObject extends ParentObject {
 // more bean info
}

这些表中的每一个都对应于数据库中的不同表。我正在使用 Hibernate 来查询 ChildObject,这将依次填充父对象的值。

我已经这样定义了我的映射文件:

<hibernate-mapping>
<class name="ParentObject"
       table="PARENT_OBJECT">
   <id name="id"
       column="parent"id">
      <generator class="assigned"/>
   </id>
   <property name="beaninfo"/>
   <!-- more properties -->
   <joined-subclass name="ChildObject" table="CHILD_OBJECT">
       <key column="CHILD_ID"/>
       <!--properties again-->
   </joined-subclass>
</class>
</hibernate-mapping>

我可以使用 hibernate 毫无问题地查询这两个表。

我用

session.createQuery("from ChildObject as child ");

这是所有基本的休眠内容。但是,我遇到的问题是我需要对查询中的所有表应用锁。

我可以使用 query.setLockType("child", LockMode.?) 设置子对象的锁定类型。但是,我似乎找不到在父表上加锁的方法。

我是 Hibernate 的新手,并且仍在努力解决一些心理障碍。问题是:如何在父表上加锁?

我想知道是否有一种方法可以在不撤消我设置的多态结构的情况下执行此操作。

【问题讨论】:

  • 我已经更新了我的答案 - 请看一下。不过,我从未处理过 Teradata,而且我在悲观锁定方面的经验有些有限,因此请谨慎对待我的建议。

标签: java hibernate polymorphism table-lock


【解决方案1】:

为什么必须锁定两个表?我之所以问,是因为根据您的尝试,可能会有替代解决方案来实现您想要的。

事情就是这样,Hibernate 通常是only locks the root table,除非你使用一些异国情调的数据库/方言。所以,很可能你已经锁定了 ParentObject 表而不是 ChildObject。

更新(基于评论):

由于您使用的是不支持FOR UPDATE 语法的外来数据库:-),Hibernate 将锁定查询中指定的“主”表(在这种情况下,“主”表是为实体映射的表在FROM 子句中列出,而不是层次结构的根 - 例如ChildObject,而不是ParentObject)。由于您想锁定两个表,我建议您尝试以下方法之一:

  1. 从查询中获取实体后,请在实体上调用session.lock()。这应该锁定层次结构的 root 表,但是我不能 100% 确定它是否会起作用,因为从技术上讲,您正在尝试“升级”已经在给定的锁上持有的锁实体。
  2. 尝试通过在查询中明确命名ParentObject 表并为其请求锁定模式来作弊:

    String hql = "select c from ChildObject c, ParentObject p where c.id = p.id";
    session.createQuery(hql)
     .setLockMode("c", LockMode.READ)
     .setLockMode("p", LockMode.READ).list();
    

【讨论】:

  • 我需要锁定两个表,因为我使用的是“异国情调”数据库 (Teradata)。它非常适合处理基于 OLAP 的查询,但是在处理基于 OLTP 的事务时它就乏善可陈了。我需要锁定两个表以允许其他事务读取和写入开始查询的表。 (我希望我这么说是在开玩笑)这很有趣,因为非根表是在我的情况下被锁定的表。不过,这是一个很好的答案。
  • 这是我试图描述的最佳答案。但是,我不确定我是否正确描述了它。我试图在查询期间“锁定”表,以便在查询期间对表运行的其他查询/更新不会被阻止。我遇到了另一个问题,即当我尝试运行查询时,setLockMode 似乎没有找到 p 对象别名的等效项。当我尝试运行查询时,出现错误:找不到别名以应用锁定模式。感谢您帮助我解决 ChssPly76 问题
  • 正如我所说,我没有使用 Teradata 的经验。它实际上是否需要基于行的锁才能运行并发查询?这通常(在“通用”数据库中)通过事务隔离级别而不是悲观锁定来处理。是否有一些“神奇”的 Teradata 特定 SQL 语句可以为您“锁定”表?如果是这样,也许您可​​以将其作为本机查询运行。如果您确实需要悲观锁定,请为org.hibernate.event.* 和 SQL 输出启用 DEBUG 日志记录;也许您会对幕后发生的事情有更深入的了解。
猜你喜欢
  • 2010-11-02
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2015-07-20
  • 2010-09-20
  • 2018-11-09
相关资源
最近更新 更多