views:

534

answers:

1

I have two objects:

public class ParentObject {
 // some basic bean info
}

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

Each of these tables corresponds to a differnet table in a database. I am using Hibernate to query the ChildObject, which will in turn populate the parent objects values.

I have defined my mapping file as so:

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

I can use hibernate to query the two tables without issue.

I use

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

This is all basic hibernate stuff. However, the part which I am having issues with is that I need to apply locks to the all the tables in the query.

I can set the lock type for the child object by using the query.setLockType("child", LockMode.?). However, I cannot seem to find a way to place a lock on the parent table.

I am new to Hibernate, and am still working around a few mental roadblocks. The question is: how can I place a lock on the parent table?

I was wondering if there was a way around having to do this without undoing the Polymorphic structure that I have set up.

+1  A: 

Why do you have to lock both tables? I'm asking because depending on what you're trying to do there may be alternative solutions to achieve what you want.

The way things are, Hibernate normally only locks the root table unless you're using some exotic database / dialect. So, chances are you're already locking your ParentObject table rather than ChildObject.

Update (based on comment):

Since you are using an exotic database :-) which doesn't support FOR UPDATE syntax, Hibernate is locking the "primary" tables as they are specified in query ("primary" in this case being table mapped for the entity listed in FROM clause, not the root of the hierarchy - e.g. ChildObject, not ParentObject). Since you want to lock both tables, I'd suggest you try one of the following:

  1. Call session.lock() on entities after you've obtained them from the query. This should lock the root table of the hierarchy, however I'm not 100% sure on whether it'll work because technically you're trying to "upgrade" the lock that's already being held on a given entity.
  2. Try to cheat by explicitly naming ParentObject table in your query and requesting lock mode for it:

    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();
    
ChssPly76
I need to lock both tables because I am using an 'exotic' database (Teradata). It is fantastic for handling OLAP based queries, however, it is lackluster when it comes to OLTP based transactions. I need to lock both tables in order to allow other transactions to read and write to the tables begin queried. (I wish I were kidding when I say that) This is interesting, since the non-root table is the table that is getting locked under my circumstances. This is a pretty good answer though.
bogertron
This is the best answer for what I attempted to describe. I am not sure if I described it properly however. I am attempting to 'lock' the table during the query so that other queries/updates run against the table during the query dont get blocked.I am encountering another issue which is when I attempt to run the query, the setLockMode does not seem to find the equivalent of the p object's alias. When i attempt to run the query i get the error: could not locate alias to apply lock mode.Thank you for helping me with the issue ChssPly76
bogertron
As I said, I've no experience with Teradata. Does it actually require row-based locks for concurrent queries to run? This is normally (in "common" databases) something handled via transaction isolation levels rather than pessimistic locking. Is there some "magic" Teradata-specific SQL statement that would "lock" the table for you? If so, perhaps you can run it as native query. If you do actually need pessimistic locking, enable DEBUG logging for `org.hibernate.event.*` and SQL output; perhaps you'd get some more insight into what's happening behind the scenes.
ChssPly76