2009-11-24 33 views
1

我有两个对象:休眠 - 适用锁父表中多态查询

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的新手,现在还在为一些心理障碍工作。问题是:如何在父表上放置一个锁?

我想知道是否有办法解决这个问题,而无需撤消我设置的多态结构。

+0

我已经更新了我的答案 - 请大家看看。不过,我从来没有处理过Teradata,而且我对悲观锁定的经验有所限制,所以请提出一些建议。 – ChssPly76 2009-11-24 07:36:03

回答

1

为什么你必须锁定两个表?我在问,因为根据你想要做的事情,可能有其他解决方案来实现你想要的。

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

更新(基于评论):

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

  1. 在你从查询中获得它们之后调用session.lock()。这应该锁定根目录表,但是我不能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(); 
    
+0

我需要锁定两个表,因为我使用的是'异国情调'的数据库(Teradata)。这对于处理基于OLAP的查询来说太棒了,但是,当涉及到基于OLTP的事务时,它却毫无用处。我需要锁定两个表,以便允许其他事务读取和写入表中开始查询。 (我希望我说的时候开玩笑) 这很有趣,因为非根表是在我的情况下被锁定的表。尽管这是一个很好的答案。 – bogertron 2009-11-24 04:19:46

+0

这是我试图描述的最佳答案。但我不确定我是否正确描述了它。我正试图在查询过程中'锁定'表,以便在查询期间其他查询/更新不会被阻止。 我遇到了另一个问题,当我试图运行查询时,setLockMode似乎没有找到p对象别名的等价物。当我尝试运行查询时出现错误:无法找到应用锁定模式的别名。 谢谢你帮我解决问题ChssPly76 – bogertron 2009-11-24 19:30:20

+0

正如我所说的,我没有Teradata的经验。它实际上是否需要基于行的锁来让并发查询运行?这通常(在“通用”数据库中)通过事务隔离级别处理而不是悲观锁定。是否有一些“神奇”Teradata特定的SQL语句可以为你“锁定”表?如果是这样,也许你可以运行它作为本机查询。如果确实需要悲观锁定,请为'org.hibernate.event。*'和SQL输出启用DEBUG日志记录;也许你会更深入地了解幕后发生的事情。 – ChssPly76 2009-11-24 19:45:16