Обновление версии спящего режима вручную

У меня есть два класса: Foo и Bar отображаются как @OneToOne (двунаправленный) с использованием Hibernate (3.6.1 final) с JPA (2.0), например -

@Entity
public class Foo{
    @Id
    private Long id;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "foo")
    private Bar bar;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "foo")
    private Qux qux;

    @Version
    private int version;

    // getters and setters omitted
}

@Entity
public class Bar{
    @Id
    private Long id;

    @OneToOne
        @JoinColumn(name = "foo_id",  nullable = false)
    private Foo foo;

    // getters and setters omitted
}

@Entity
public class Qux {
    @Id
    private Long id;

    @OneToOne
        @JoinColumn(name = "foo_id",  nullable = false)
    private Foo foo;

    // getters and setters omitted
}

Обратите внимание: у Bar и Qux нет столбца @Version

Если мы обновим Bar, то hibernate не будет увеличивать версию Foo и Qux. Но наша бизнес-логика требует - если кто-то обновляет Bar в Foo, а другой поток пытается обновить Qux того же Foo, но не имеет обновленного Bar и наоборот, то такие обновления должны завершаться ошибкой.
Поскольку hibernate не работает обновить свойство версии Foo, если мы обновим Bar, мы решили обновить версию Foo вручную (я знаю, что это довольно странно и не рекомендуется), если мы обновим Bar и Qux.
Это прекрасно работает... но я Я беспокоюсь о некоторых крайних случаях параллелизма, которые могут привести к сбою или непреднамеренному поведению.
Безопасно ли делать такие настройки с версией для этой цели? ИЛИ есть ли другая лучшая альтернатива этому (я уже пробовал оптимистическое/пессимистическое увеличение силы)


person Premraj    schedule 14.03.2011    source источник


Ответы (1)


Правильный способ принудительного обновления версии следующий:

em.lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

Он предназначен для использования в таких случаях.

Можно использовать и другие методы EntityManager, требующие LockModeType.

person axtavt    schedule 14.03.2011
comment
но чтобы использовать это, мне нужно свойство версии в Bar и Qux, верно? - person Premraj; 15.03.2011
comment
Я пытаюсь использовать этот код: Foo entity = new Foo(); em.persist(foo); int oldVersion = entity.getVersion(); em.lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT); return oldVersion == entity.getVersion(); Я ожидаю, что это ложь, но это правда. - person Zufar Muhamadeev; 09.12.2017