Как использовать single sessionFactory для hibernate Intercepter

Я использую Hibernate Interceptor с (hibernate 4.x). Я хочу выполнить некоторую операцию по методу сохранения сеанса. Поэтому я расширяю EmptyInterceptor.

Он имеет следующие методы:

onSave() //when save operation is preformed.
postFlush() //called after committed into database 

ПРОБЛЕМА: в postFlush() я хочу выполнить операцию SAVE. Так что мой контроль застрял в петле. потому что когда session.save() вызывается моими вызовами, метод onSave() и postFlush() класса EmptyInterceptor вызывается для перехвата операции SAVE.

ЧТОБЫ устранить эту проблему, я использовал ДВЕ фабрики сеансов. 1 для выполнения операций сеанса (сохранение, обновление и т. д.) и 2-й для HibernateIntercepter.

Но меня беспокоит, как я могу решить эту проблему с помощью одного сеанса Factory ??

открытый класс AudiLogInterceptor расширяет EmptyInterceptor {

public boolean onSave(Object entity, Serializable id, Object[] state,
        String[] propertyNames, Type[] types) {
    return false;
}

// called after committed into database
public void postFlush(Iterator iterator) {
    // want to perform SAVE operation here with Session.save()
    // But whenever I open new seesion here. It falls in loop
    Session tempSession = HibernateUtil.hibernateTemplateLog
            .getSessionFactory().openSession();

    try {
        Item item = new Item();
        item.setName("anyItem");
        item.setValue("anyValue");
        tempSession.save(item);
        tempSession.flush();
    } finally {
        tempSession.close();
    }
    }
} 

person user3029929    schedule 17.02.2014    source источник


Ответы (1)


Вы не используете перехватчики для сохранения объектов. Вы используете его для изменения/форматирования элементов и позволяете объекту сеанса делать все остальное за вас, но не добавлять новые элементы.

Если вы действительно хотите добавить строку в конце flush() или commit(), вы можете использовать Spring-AOP, чтобы сделать это как один из вариантов. Там вы можете добавить советы в службы гибернации, чтобы вы могли сохранить что-то сразу после запуска метода.

Обходной путь Я думал следующее.

public void postFlush(Iterator iterator) {


for(; iterator.hasNext();) {
   if(!(iterator.next() instanceof Item)){ //<<<<< You verify if you are saving Item or //other objects, if saving Item, skip this block.

   Session tempSession = HibernateUtil.hibernateTemplateLog
            .getSessionFactory().openSession();

    try {
        Item item = new Item();
        item.setName("anyItem");
        item.setValue("anyValue");
        tempSession.save(item);
        tempSession.flush();
    } finally {
        tempSession.close();
    }
}
}
    }
} 
person Zeus    schedule 17.02.2014
comment
На самом деле я использую hibernate Interceptor для ПРОВЕРКИ ПРОВЕРКИ. Означает, что всякий раз, когда будет выполняться какая-либо операция SAVE или UPDATE, мой перехватчик захватит этот метод и вставит новую запись в таблицу журнала аудита (информация об объекте. Что на самом деле было раньше и что сейчас). Вот код ссылки. mkyong.com/hibernate/hibernate-interceptor-example-audit-log - person user3029929; 17.02.2014
comment
В приведенном вами примере ссылки автор привязывал перехватчик к определенному сеансу, поэтому, если он сохранит или обновит, у него не будет проблемы с циклом. Вы привязываете его к сеансу? или вы применили перехватчик ко всему приложению? Если вы подали заявку на сессию, то, пожалуйста, взгляните на обходной путь, который я упомянул, определите объект, который находится в пост-сбросе, если это объект AuditLog, то пропустите блок сохранения аудита, поэтому последующее сохранение будет не вызываться, чтобы программа не зацикливалась. - person Zeus; 17.02.2014
comment
Не могли бы вы сообщить мне, как привязать перехватчик к сеансу? Я не могу найти метод на sessionfactory, который принимает Connection в качестве аргумента - person user3029929; 18.02.2014
comment
В примере см. шаг № 7. Пример: mkyong.com/hibernate /hibernate-interceptor-example-audit-log. Кроме того, почему вы ищете аргумент соединения? - person Zeus; 18.02.2014
comment
На шаге №7 объект-перехватчик передается в метод .openSession(). Но я использую hibernate 4.2.x, в котором у нас нет метода openSession() с аргументом. Итак, как мне передать ссылку на сеанс в мой класс-перехватчик? (Если я не использую статический объект сеанса и не передаю через него конструктор класса AuditLogInterceptor) ››››››››››››››››››› Перехватчик AuditLogInterceptor = new AuditLogInterceptor(); сеанс = HibernateUtil.getSessionFactory().openSession(перехватчик); interceptor.setSession(сессия); - person user3029929; 19.02.2014
comment
Я все еще не мог этого сделать. Проблема все еще существует. Но я только что добавил обходной путь и использовал ДВЕ фабрики сеансов: одну для моих операций гибернации, другую для операции ведения журнала аудита (в которой я передал ссылку на класс перехватчика). НО я знаю, что это не очень хороший выбор, и я действительно хочу использовать только одну фабрику сеансов и хочу связать свой перехватчик с одним сеансом. - person user3029929; 21.02.2014