Hibernate / JPA @Version и @Generated, вызывающие исключение StaleObjectStateException - PullRequest
1 голос
/ 20 марта 2012

Использование Spring 3.1 / JPA 2, предоставляемого Hibernate 4.1.0.

У меня есть базовый класс для всех моих сущностей, который обеспечивает базовые возможности аудита (метка времени обновления, номер версии и т. Д.), Поскольку другие приложения обращаютсянаша база данных, они должны быть установлены через триггер.

Мое отображение выглядит следующим образом:

public abstract class AbstractBaseModel implements Serializable {

@Version
@Generated(GenerationTime.ALWAYS)
@Column(name = "VERSION", insertable = false, updatable = false)
protected Long version;

@Generated(GenerationTime.ALWAYS)
@Column(name = "UPDATE_TIMESTAMP", insertable = false, updatable = false)
protected Date updateDate;
...
}

Метод org.hibernate.engine.internal.increment(...) всегда вызывается при совершении транзакции - и в результате получается StaleObjectStateException.

Как ни странно, если я установлю GenerationTime.NEVER в столбце версии, hibernate по-прежнему увеличивает версию, но сохраняется правильно.Проблема заключается в том, что даже если версия в базе данных не обновляется (например, нет изменений в таблице), версия, возвращенная после слияния, будет на 1 больше, чем значение базы данных, что, очевидно, вызовет проблемы при последующем сохранении.

Я ожидаю, что GenerationTime.ALWAYS скажет hibernate никогда не пытаться увеличивать версию и полагаться на базу данных, чтобы сделать это, а затем после вставки / обновления выбрать обновленное значение.

Может кто-нибудь сказать мне, где я ошибся в моем понимании и реализации?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Вы можете сделать это, используя DB, указав следующее в определении столбца SQL и в сопоставлении сущностей. Пример ниже для MySQL:

create table if not exists table_name (
    ...
    modified timestamp default current_timestamp on update current_timestamp not null,
    ...
);

И в коде:

@Version
@Column(name = "modified", columnDefinition = "timestamp default current_timestamp on update current_timestamp")
private Date modified;
0 голосов
/ 18 апреля 2012

У меня нет ответа на ваш актуальный вопрос, но у меня есть решение вашей проблемы.:)

В Hibernate вполне допустимо сделать это:

@Version
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "UPDATE_TIMESTAMP"
private Date updateDate;

Это также сделает дату обновления вашей версией.Это одновременно меньше и автоматически обновляет его при каждом слиянии в сущности.

Кстати: я предлагаю сделать членов приватными и добавить get ters и set ters к классу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...