У меня есть два класса: 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.
Это прекрасно работает... но я Я беспокоюсь о некоторых крайних случаях параллелизма, которые могут привести к сбою или непреднамеренному поведению.
Безопасно ли делать такие настройки с версией для этой цели? ИЛИ есть ли другая лучшая альтернатива этому (я уже пробовал оптимистическое/пессимистическое увеличение силы)