Перехватчик гибернации: как переопределить onCollectionUpdate и onCollectionRecreate, чтобы не заполнять мои объекты значениями базы данных? - PullRequest
3 голосов
/ 22 июня 2011

Я расширяю org.hibernate.EmptyInterceptor для расшифровки и шифрования полей. Цель состоит в том, чтобы всегда иметь объекты домена в памяти в дешифрованном состоянии и всегда иметь сохраненные значения базы данных в зашифрованном состоянии.

Я переопределил методы preFlush и postFlush для EmptyInterceptor. preFlush шифрует поля объекта, а postFlush расшифровывает поля объекта. Всякий раз, когда Hibernate сбрасывает объект, поля сохраняются в базе данных в зашифрованном виде. Я могу продолжать получать доступ к полям объекта в памяти в незашифрованном состоянии. Мои методы preFlush и postFlush работают хорошо для меня.

Во многих случаях моему приложению нужно загружать объекты, которые уже были сохранены в базе данных. Я переопределил метод onLoad EmptyInterceptor для расшифровки значений в базе данных. Загруженные объекты находятся в дешифрованном состоянии после вызова onLoad. Однако всякий раз, когда Hibernate выполняет несвязанный запрос, мой объект в памяти извлекает зашифрованные значения из базы данных. У меня остался непригодный объект в памяти, который находится в зашифрованном состоянии.

Я подозреваю, что могу переопределить onCollectionUpdate и onCollectionRecreate для EmptyInterceptor, чтобы hibernate прекратил обновление моего обновления значениями из базы данных. Я попытался просто установить для параметра коллекции значение null в onCollectionUpdate и onCollectionRecreate, но проблема сохраняется.

Есть ли какие-либо идеи о том, как я могу остановить спящий режим от выполнения обновлений коллекции и воссоздания объектов, которые необходимо зашифровать в базе данных?

Ниже приведен фрагмент моего класса CryptoInterceptor. Я включил мой текущий метод onCollectionRecreate, который устанавливает для параметра коллекции значение null. Мой метод onCollectionUpdate похож.

public class CryptoInterceptor extends EmptyInterceptor
{

public static final Set<Class> CRYPTO_CLASSES = Collections.unmodifiableSet(new HashSet<Class>(Arrays.asList(new Class[]
    { User.class, Order.class, Account.class})));

@Override
public void onCollectionRecreate(Object aCollection, Serializable aKey) throws CallbackException
    {
        PersistentCollection persistentColl = (PersistentCollection)aCollection;

        Object aEntity = null;

        aEntity = persistentColl.getOwner();

       if (aEntity == null)
       {
           return;
       }

        try
        {
            Class clazz = Class.forName(aEntity.getClass().getName());

            if (!CRYPTO_CLASSES.contains(clazz))
            {
                return;
            }
           else
           {
                aCollection = null;
           }
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }

        return;
    }
}

Из отладки я знаю, что Hibernate всегда передает объект, который реализует интерфейс org.hibernate.collection.PersistentCollection для объекта коллекции.

Ответы [ 2 ]

1 голос
/ 26 марта 2015

Я знаю, что уже слишком поздно для этого, но так как я нашел этот пост полезным в качестве руководства по шифрованию, я укажу, что вы не можете установить

 aCollection = null;

внутри функции, так как коллекцияаргумент и так просто ссылка на объект.Если вы действительно хотите это сделать, вы должны сделать что-то вроде

aCollection.clear();
0 голосов
/ 22 июня 2011

вы можете попробовать использовать DefaultLoadEventListener для работы .. идея здесь заключается в 1. контролировать загрузку объектов (в частности коллекций). 2. контролировать данные в объектах коллекции (шифрование и дешифрование).

Есть довольно много слушателей, которые могут сделать эту работу за вас.

...