Пессимистическая блокировка Hibernate не работает с полиморфным запросом

У меня следующая иерархия классов:

@Entity
@Table(name = "BaseThing")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class BaseThing implements Serializable {

    @Id
    @Column(name = "id", nullable = false)
    private Long id;

    @Basic(optional = false)
    @Column(name = "name", nullable = false, length = 48)
    private String name;
    ...
}

@Entity
@Table(name = "ConcreteThing")
public class ConcreteThing extends BaseThing {

    @Column(name = "aprop", nullable = false, length = 12)
    private String aProp;

    ...
}

@Entity
@Table(name = "AnotherConcreteThing")
public class AnotherConcreteThing extends BaseThing {

    @Column(name = "anotherprop", nullable = false, length = 12)
    private String anotherProp;

    ...
}

Я пытаюсь прочитать и заблокировать экземпляр ConcreteThing, чтобы никакая другая транзакция не могла его прочитать, используя спящий режим LockOptions.UPGRADE.

Теперь функция:

BaseThing thing = (BaseThing) session.get(BaseThing.class, id, LockOptions.UPGRADE);

не работает - синтаксис «выбрать для обновления» не создается спящим режимом, поэтому для этого объекта нет пессимистической блокировки

пока:

BaseThing entity = (BaseThing) session.get(BaseThing.class, id);
session.refresh(entity, LockOptions.UPGRADE));

работает - для операции обновления генерируется синтаксис «выбрать для обновления».

Разница между функциями refresh () и get () заключается в том, что функция get () использует внешнее левое соединение для выбора конкретного объекта, а refresh () использует внутреннее соединение для выбора конкретного объекта.

есть ли разница между этими соединениями в контексте пессимистической блокировки?

Спасибо!


person eitann    schedule 01.07.2015    source источник


Ответы (1)


Некоторые базы данных не поддерживают выбор для обновления с внешним соединением.

в моем случае я использую DB2 версии 10.5, которая поддерживает. так что проблема остается.

Покопавшись в коде гибернации, я обнаружил, что в DB2Dialect есть функция supportsOuterJoinForUpdate(), которая возвращает false, хотя предполагается, что она возвращает true, потому что BD2 поддерживает этот тип выбора. это ошибка гибернации. расширение DB2Dialect и возвращение true для этой функции устранили проблему для меня.

person eitann    schedule 14.07.2015