Обход ошибки Hibernate SQLServerDialect с пессимистическими блокировками и наследованием одной таблицы ⇐ JAVA
Обход ошибки Hibernate SQLServerDialect с пессимистическими блокировками и наследованием одной таблицы
У нас есть приложение Quarkus, которое отлично работает с Hibernate 6.2, но не работает с Hibernate 6.4. Он использует SQL-сервер. Код похож на:
@Entity общественный класс А { @ManyToOne (необязательно = правда) Б б; } @Сущность общественный класс B { @ManyToOne (необязательно = ложь) С1 с; } @Inheritance (стратегия = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "type", DiscriminatorType = DiscriminatorType.STRING) публичный абстрактный класс CBase { } @Сущность @DiscriminatorValue("1") публичный класс C1 расширяет CBase { } @Сущность @DiscriminatorValue("2") публичный класс C2 расширяет CBase { } Код, который не работает:
var m =entityManager.find(A.class, id, LockModeType.PESSIMISTIC_WRITE); В Hibernate 6.2 это будет выглядеть следующим образом:
выбрать... из a_0 с помощью (updlock,holdlock,rowlock) левое соединение b b_0 с (updlock,holdlock,rowlock) на b_0.a_id = a_0.id левое соединение c c_0 с помощью (updlock,holdlock,rowlock) на c_0.b_id = b_0.id и c_0.type = '1' ... Но с Hibernate 6.4:
выбрать... из a_0 с помощью (updlock,holdlock,rowlock) левое соединение b b_0 с (updlock,holdlock,rowlock) на b_0.a_id = a_0.id левое соединение (выберите * из c, где type = '1') c_0 с (updlock,holdlock,rowlock) на c_0.b_id = b_0.id ... По какой-то причине условие для конкретного подтипа было перенесено из фильтра объединения в подвыбор. Однако невозможно применить подсказки блокировки к дополнительному выбору, для этого нужна таблица.
Как только мы создадим воспроизводитель, мы сообщим об этом как об ошибке Hibernate, но в то же время нам запрещено обновляться.
РЕДАКТИРОВАТЬ:
Можно ли каким-либо образом настроить SQLServerDialect, чтобы он вернулся к старому стилю? Я не могу найти никаких свойств конфигурации для этого, но, возможно, они где-то существуют?
График выборки решает проблему в этом конкретном случае (найти):
Map props = new HashMap(); props.put("jakarta.persistence.fetchgraph",entityManager.createEntityGraph(entityClass)); Значение T =entityManager.find(entityClass, key, LockModeType.PESSIMISTIC_WRITE, реквизит); Он блокирует только основную таблицу, и это нормально. Однако было бы неплохо использовать более общее решение, поскольку существуют более сложные запросы, использующие блокировки, которые труднее исправить.
У нас есть приложение Quarkus, которое отлично работает с Hibernate 6.2, но не работает с Hibernate 6.4. Он использует SQL-сервер. Код похож на:
@Entity общественный класс А { @ManyToOne (необязательно = правда) Б б; } @Сущность общественный класс B { @ManyToOne (необязательно = ложь) С1 с; } @Inheritance (стратегия = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "type", DiscriminatorType = DiscriminatorType.STRING) публичный абстрактный класс CBase { } @Сущность @DiscriminatorValue("1") публичный класс C1 расширяет CBase { } @Сущность @DiscriminatorValue("2") публичный класс C2 расширяет CBase { } Код, который не работает:
var m =entityManager.find(A.class, id, LockModeType.PESSIMISTIC_WRITE); В Hibernate 6.2 это будет выглядеть следующим образом:
выбрать... из a_0 с помощью (updlock,holdlock,rowlock) левое соединение b b_0 с (updlock,holdlock,rowlock) на b_0.a_id = a_0.id левое соединение c c_0 с помощью (updlock,holdlock,rowlock) на c_0.b_id = b_0.id и c_0.type = '1' ... Но с Hibernate 6.4:
выбрать... из a_0 с помощью (updlock,holdlock,rowlock) левое соединение b b_0 с (updlock,holdlock,rowlock) на b_0.a_id = a_0.id левое соединение (выберите * из c, где type = '1') c_0 с (updlock,holdlock,rowlock) на c_0.b_id = b_0.id ... По какой-то причине условие для конкретного подтипа было перенесено из фильтра объединения в подвыбор. Однако невозможно применить подсказки блокировки к дополнительному выбору, для этого нужна таблица.
Как только мы создадим воспроизводитель, мы сообщим об этом как об ошибке Hibernate, но в то же время нам запрещено обновляться.
РЕДАКТИРОВАТЬ:
Можно ли каким-либо образом настроить SQLServerDialect, чтобы он вернулся к старому стилю? Я не могу найти никаких свойств конфигурации для этого, но, возможно, они где-то существуют?
График выборки решает проблему в этом конкретном случае (найти):
Map props = new HashMap(); props.put("jakarta.persistence.fetchgraph",entityManager.createEntityGraph(entityClass)); Значение T =entityManager.find(entityClass, key, LockModeType.PESSIMISTIC_WRITE, реквизит); Он блокирует только основную таблицу, и это нормально. Однако было бы неплохо использовать более общее решение, поскольку существуют более сложные запросы, использующие блокировки, которые труднее исправить.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Многопроцессорность Python с несколькими блокировками медленнее, чем с одной блокировкой
Anonymous » » в форуме Python - 0 Ответы
- 10 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Многопроцессорность Python с несколькими блокировками медленнее, чем с одной блокировкой
Anonymous » » в форуме Python - 0 Ответы
- 9 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Многопроцессорность Python с несколькими блокировками медленнее, чем с одной блокировкой
Anonymous » » в форуме Python - 0 Ответы
- 10 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Проблема с Hibernate 6 и многоуровневым наследованием: добавление объединений
Anonymous » » в форуме JAVA - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Проблема с Hibernate 6 и многоуровневым наследованием: добавление объединений
Anonymous » » в форуме JAVA - 0 Ответы
- 16 Просмотры
-
Последнее сообщение Anonymous
-