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 {
...
}