При обновлении текущей метки времени и JPA

у меня есть сущность с полями

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "edit_timestamp", 
        columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private Date editTimestamp;

@Version
@Column(name = "edit_count")
private short editCount;

private String text;

когда я пытаюсь обновить с Весна-данные-JPA, Я наблюдаю, что edit_count был увеличен, но edit_timestamp все еще остается тем же. Если я вручную вызываю SQL

UPDATE post SET TEXT='456' WHERE post_id=1;

edit_timestamp обновляется. Если я добавлю

@PreUpdate
protected void onUpdate() {
    editTimestamp = new Date();
}

он работает Вт вопрос/вывода. Мой вопрос в том, почему w / o @PreUpdate edit_timestamp не обновляется?

2 ответов


Это старый вопрос, но я подумал, что отвечу на него, если кто-нибудь еще найдет его полезным. Я думаю, вам нужно изменить аннотацию столбца, чтобы включить updatable = false. Это приведет к тому, что столбец edit_timestamp не будет отображаться в sql update, поэтому поставщик JPA не будет включать текущее значение поля, которое заставляет его переопределять значение по умолчанию.

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "edit_timestamp", 
        updatable = false
        columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private Date editTimestamp;

потому что в вашем первоначальном наборе аннотаций все, что вы сказали ему о столбце edit_timestamp, - это то, что это временная метка; JPA не знает, что ему нужно ее обновить. Я предполагаю, что при ручном выполнении инструкции SQL у вас есть какой-то триггер on - update, который изменяет эти поля для вас, но перезаписывается данными, поступающими от сохраненной сущности при ее обновлении.
Если вам не нужен "отредактированный" счетчик / метка времени, попробуйте удалить их из entity, и посмотреть, работает ли это. В противном случае, у вас есть рабочее решение.