Спящий режим: Грязная проверка и обновление только от грязных атрибутов?

В "добрые старые дни JDBC" я написал много кода SQL, в котором были очень целевые обновления только "атрибутов/членов", которые были фактически изменены:

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

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

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

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

Мои вопросы:

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

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

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

Ответы

Ответ 1

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

Ответ 2

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

public class Person {

    private Integer id;

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

    // getter and setter's

}

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

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

person.setName("jean");

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

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

Поскольку Hibernate кэширует каждый запрос SQL (INSERT, UPDATE, SELECT) для объекта EACH, он просто обновляет то, что вы действительно хотите.

Ответ 4

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

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

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

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