Hibernate: грязная проверка и только обновление грязных атрибутов? - PullRequest
17 голосов
/ 20 апреля 2010

В «старые добрые времена JDBC» я написал много SQL-кода, который делал очень точные обновления только тех «атрибутов / членов», которые действительно были изменены:

Например, рассмотрим объект со следующими членами:

public String name;
public String address;
public Date date;

Если бы в каком-либо бизнес-методе было изменено только date, я бы выдал только SQL UPDATE для члена date.

Однако кажется (это мое «впечатление» о Hibernate), что при работе со стандартным отображением Hibernate (отображением полного класса) даже обновления только одного члена приводят к полному обновлению объекта в сгенерированных операторах SQL от Hibernate.

Мои вопросы:

  1. Верно ли это наблюдение, что Hibernate не интеллектуально проверяет (в полностью сопоставленном классе), какие элементы были изменены, а затем выпускает обновления только для определенных измененных элементов, но скорее всегда будет обновлять (в сгенерированном операторе SQL Update) все сопоставленные члены (класса), даже если они не были изменены (в случае, если объект загрязнен из-за того, что один член загрязнен ...)

  2. Что я могу сделать, чтобы Hibernate обновлял только те элементы, которые были изменены? Я ищу решение, чтобы Hibernate обновлял только измененного участника.

(Я знаю, что Hibernate выполняет некоторую работу по проверке на грязные объекты, но, насколько я знаю, эта грязная проверка важна только для определения, является ли объект в целом грязным, а не какой-либо один элемент загрязнен.)

Ответы [ 4 ]

15 голосов
/ 20 апреля 2010

На самом деле, вы можете указать опции dynamic-update и dynamic-insert в отображении класса. Это делает именно это. Подробнее здесь .

5 голосов
/ 20 апреля 2010

Hibernate просто обновите то, что вы действительно хотите

public class Person {

    private Integer id;

    public String name;
    public String address;
    public Date date;

    // getter's and setter's

}

И вы делаете что-то вроде

Person person = (Person) sessionFactory.openSession().get(Person.class, personId);

person.setName("jean");

Hibernate достаточно умен, чтобы знать, что имя свойства было изменено. Хотя вы можете увидеть свой журнал следующим образом

UPDATE PERSON (NAME, ADDRESS, DATE) VALUES (?, ?, ?);

Поскольку Hibernate кэширует каждый запрос SQL (INSERT, UPDATE, SELECT) для КАЖДОЙ сущности, опять же, он просто обновляет то, что вам действительно нужно.

2 голосов
/ 10 июля 2014

Вы можете оптимизировать грязную проверку, реализовав такие интерфейсы, как CustomEntityDirtinessStrategy или Interceptor. См рабочий пример на http://prismoskills.appspot.com/lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp

0 голосов
/ 24 ноября 2011

Я думаю, что динамическое обновление хорошо, если у вас большая нагрузка на базу данных и один или несколько индексов для воссоздания при полном обновлении (где обновляются все столбцы, в том числе с неизменными значениями).

Возможно, некоторые СУБД распознают, если UPDATE устанавливает уже существующее значение, чтобы не обновлять индекс, включающий этот столбец. Но многие, кажется, слишком «глупы», чтобы признать это (или не проверять это по соображениям производительности).

Загрузка на стороне клиента для создания запросов SQL не является проблемой для большинства клиентских приложений БД. Интерпретация SQL в БД должна занимать меньше времени, чем воссоздание большого индекса.

Пожалуйста, поправьте меня, если я ошибаюсь!

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