Как избежать чрезмерных зимних приливов в БД - PullRequest
4 голосов
/ 22 марта 2012

Я использую Play Framework с Hibernate в качестве поставщика JPA, и я заметил, что если у объекта есть член Blob, он всегда будет сбрасываться в БД, даже если я ничего не изменил в нем, идаже если я не читаю значение Blob.

Blob - это UserType, определенный в Play. Вот исходный код .Основная идея этого класса - сохранить фактические данные в файловой системе и сохранить только указатель (UUID) в таблице БД.

Из этого SO ответа я понял, что что-то в коде Blob должно вносить изменения между временем загрузки из БД и временем его проверки Hibernate.Есть также этот ответ , который предполагает, что это может быть что-то еще.

Как я могу изменить класс Blob, чтобы избежать сброса базы данных, если не было внесено никаких изменений?


Ответ GreyBeardedGeek оказался верным.Текущая реализация equals возвращает true только для объектов с одинаковыми идентификаторами и всегда возвращает false для нулей.

Изменение этого значения:

public boolean equals(Object o, Object o1) throws HibernateException {
    return o == null ? false : o.equals(o1);
}

на это:

private static boolean equal(Object a, Object b) {
  return a == b || (a != null && a.equals(b));
}

public boolean equals(Object a, Object b) throws HibernateException {
    if(a instanceof Blob && b instanceof Blob) {
        return equal(((Blob)a).UUID, ((Blob)b).UUID) &&
                equal(((Blob)a).type, ((Blob)b).type);
    }
    return equal(a, b);
}

убрал все чрезмерные обновления БД.

1 Ответ

5 голосов
/ 22 марта 2012

Вы должны на самом деле отладить это, чтобы узнать, но я подозреваю, что проблема с hashcode() и equals(). Первое, что я бы проверил, это реализация hashcode() и equals() в классе, который вы сохраняете с Blob UserType - убедитесь, что они работают согласованно, и следуйте правилам - например,. если equals() возвращает false, когда он используется для сравнения «старого» и «нового» состояния вашего объекта, он будет сохраняться.

...