JPA2.0/Hibernate: Почему JPA запускает запрос для обновления всех значений столбцов, даже некоторые состояния управляемых beans изменены?

Я использую JPA2.0 с Hibernate.

Например, у меня есть объект JPA для таблицы ниже:

User [userId, userName, userAddress]

Я могу получить пользовательский объект, используя метод find():

User user = entityManager.find(User.class , 1L); // 1L is user id

Теперь, если я изменю любое пользовательское состояние (скажем, имя пользователя) на том же пользовательском объекте, который я выбрал выше:

user.setUserName("Narendra");

И выполните слияние с помощью метода merge():

entityManager.merge(user);

Слияние выполняется успешно с нижеследующим запросом, который запускается JPA/спящий режим при слиянии:

Hibernate: update User set USERID =?, USERNAME=?, USERADDRESS=? where USERID=?

Вот мой вопрос: если я изменил только состояние имени пользователя в сущности пользователя, я не изменил userId, userAddress и т.д. JPA должен был запустить ниже запроса (только для изменения имени пользователя), а не над запросом.

 Hibernate: update User set USERNAME=? where USERID=?

Есть идеи на нем?

Ответ 1

Посмотрите на свойство dynamic-update.

dynamic-update (необязательно - по умолчанию - false): указывает, что UPDATE SQL должен быть сгенерирован во время выполнения и может содержать только те столбцы, значения которых изменены.

Учитывайте, что динамические обновления могут иметь некоторое влияние на производительность. Там немного накладных расходов, связанных с использованием его, и это может быть контрпродуктивным, если у вас нет большой (возможно, старой) таблицы с большим количеством столбцов, которые вряд ли будут изменены. См. Этот связанный с ним вопрос Hibernate: динамическое обновление динамической вставки - Эффекты производительности.

Hibernate < 4,0

Если вы используете аннотации Hibernate, используйте специальную аннотацию @Entity вместе с JPA one:

@org.hibernate.annotations.Entity(dynamicUpdate = true)

Если вы используете сопоставления XML:

<class name="User" table="user" dynamic-update="true">

Hibernate >= 4.0

Аннотирование @Entity, специфичное для гибернации, устарело в Hibernate 4.0 и должно исчезнуть в 4.1. Правильный способ использования динамических обновлений состоит в том, чтобы теперь аннотировать объект @DynamicUpdate (спасибо @Tiny для головок).

Ответ 2

Также может использоваться как аннотация:

import org.hibernate.annotations.DynamicUpdate;

@Entity
@DynamicUpdate
@Table(name = "payments")
public class Payment {
    ...
}