JPA Entity Manager Объединение без изменений в объекте - PullRequest
0 голосов
/ 22 мая 2019

Я пытаюсь использовать метод слияния Entity Manager для обновления объекта в базе данных, когда в объекте нет изменений.Скажем, строка имеет следующие атрибуты:

id             DECIMAL(11) NOT NULL,
name           CHAR(20) NOT NULL, 
lastModified   TIMESTAMP NOT NULL FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP

И, скажем, у меня есть объект (назовем его Person) в базе данных со следующими атрибутами:

{id: 1, name: "example", lastModified: 2019-05-22 16:24:54.771}

Итак, lastModifiedАтрибут - это то, что БД обновляет каждый раз, когда в строке происходит изменение.

Теперь, когда я сначала выбираю объект, а затем обновляю имя человека до «example» (то же значение, которое у него уже естьв базе данных), а затем с помощью слияния для его обновления атрибут lastModified, по-видимому, не обновляется в базе данных.т.е.

Person person = em.find(Person.class, 1)
person.setName("example")
em.merge(person)

После вышеописанных действий lastModified по-прежнему 2019-05-22 16: 24: 54.771 (так же, как и ранее).Теперь, если бы я изменил имя, т.е.

Person person = em.find(Person.class, 1)
person.setName("new name")
em.merge(person)

Так что теперь lastModified также обновился бы.

Любая помощь с этим?Может кто-нибудь объяснить мне, почему строка не обновляется, если в объект не внесены изменения?:) Спасибо!

1 Ответ

1 голос
/ 22 мая 2019

Когда вы используете merge, Hibernate сначала запускает оператор Select в кортеже, который вы пытаетесь объединить.Этот выбор выполняется, чтобы получить последнее состояние кортежа, чтобы затем запустить обновление в базе данных с данными, которые изменились в вашем кортеже.

Как вы сказали в своем примере, у вас нетизменил любые данные, так как вы пытаетесь обновить имя таким же, каким оно было раньше, поэтому hibernate не будет запускать никаких обновлений в базе данных.

Подробнее об этом вы можете узнать, обратившись к Hibernate Dirty CheckingМеханизм.

Если вы действительно хотите обновить этот столбец, даже если никакие данные не были изменены, вы должны сделать это на уровне приложения, установив его вручную при сохранении объекта Person:

person.setLastModified(LocalDateTime.now())

...