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

StackOverflow https://stackoverflow.com/questions/1787224

Вопрос

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

public class ParentObject {
 // some basic bean info
}

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

Каждая из этих таблиц соответствует другой таблице в базе данных.Я использую Hibernate для запроса дочернего объекта, который, в свою очередь, заполнит значения родительских объектов.

Я определил свой файл сопоставления следующим образом:

<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("дочерний", LockMode.?).Однако, похоже, я не могу найти способ установить блокировку на родительскую таблицу.

Я новичок в Гибернации и все еще пытаюсь обойти несколько ментальных препятствий.Вопрос в том,:как я могу установить блокировку на родительскую таблицу?

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

Это было полезно?

Решение

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

При том, как обстоят дела, переходите в спящий режим в обычном режиме блокирует только корневую таблицу если только вы не используете какую-нибудь экзотическую базу данных / диалект.Так что, скорее всего, вы уже запираете свой ParentObject стол, а не ChildObject.

Обновить (основано на комментарии):

Поскольку вы используете экзотическую базу данных :-), которая не поддерживает FOR UPDATE синтаксис, Гибернация блокирует "первичные" таблицы в том виде, в каком они указаны в запросе ("первичная" в данном случае является таблицей, сопоставленной для объекта, указанного в 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();
    
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top