Hibernate - применять блокировки к родительским таблицам в полиморфных запросах

У меня есть два объекта:

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, и все еще работаю над несколькими умственными препятствиями. Вопрос: как я могу установить блокировку на родительский стол?

Мне было интересно, есть ли способ сделать это, не отменив созданную мною Полиморфную структуру.

1 ответ

Решение

Почему вы должны заблокировать обе таблицы? Я спрашиваю, потому что в зависимости от того, что вы пытаетесь сделать, могут быть альтернативные решения для достижения того, чего вы хотите.

Таким образом, Hibernate обычно блокирует только корневую таблицу, если вы не используете какую-то экзотическую базу данных / диалект. Так что, скорее всего, вы уже блокируете 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();
    
Другие вопросы по тегам