2013-10-01 2 views
0

я хочу знать, когда же зимуют fulshes контекста сеанса, когда я называю сессия = session.getCurrentSession()Hibernate PersistenceContext сессия Flush

Дело в том, у меня есть 2 метода в моем дао призывающих getCurrentSession(), когда я обрабатывать обновление делает вызов getCurrentSession() в entitys пустуют:

SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];...) 

Как я могу сделать это entitys сохраняться от выбора метода к методу обновления?

Вот мои методы:

public List<SystemConfiguration> getListConfigurations() { 
    List<SystemConfiguration> lista = new ArrayList<SystemConfiguration>(); 
    Session session = null; 
    Query query = null; 

    String sql = "from SystemConfiguration where description = :desc"; 
    try { 
     /* BEFORE 
      session = SessionFactoryUtil.getInstance().getCurrentSession(); 
     @SuppressWarnings("unused") 
     Transaction ta = session.beginTransaction(); */ 
      //FOLLOWING LINE SOLVED THE PROBLEM 
      session = SessionFactoryUtil.getInstance().openSession(); 
     query = session.createQuery(sql); 

     query.setString("desc", "configuracion"); 
     lista = query.list(); 

     return lista; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 


public void updateConfigurations(List<SystemConfiguration> configs) throws Exception{ 
     Session sess = null; 
     Transaction tx = null; 
     try { 
        //BEFORE 
      //sess = SessionFactoryUtil.getInstance().getCurrentSession(); 
        //FOLLOWING LINE SOLVED THE PROBLEM 
       sess = SessionFactoryUtil.getInstance().openSession(new SystemConfigurationInterceptor()); 
      tx = sess.beginTransaction(); 
      for (SystemConfiguration sys : configs) { 
        sess.update(sys); 
      } 
      tx.commit(); 
     } // try 
     catch (Exception e) { 
      e.printStackTrace(); 
      if (tx != null && tx.isActive()) { 
       tx.rollback(); 
      } // if 
      throw e; 
     } 
    } 

И это мой перехватчик:

public class SystemConfigurationInterceptor extends EmptyInterceptor { 
      private int updates; 
     private int creates; 
     private int loads; 
     public void onDelete(Object entity, 
          Serializable id, 
          Object[] state, 
          String[] propertyNames, 
          Type[] types) { 
      // do nothing 
     } 

     // This method is called when Entity object gets updated. 
     public boolean onFlushDirty(Object entity, 
            Serializable id, 
            Object[] currentState, 
            Object[] previousState, 
            String[] propertyNames, 
            Type[] types) { 

      if (entity instanceof SystemConfiguration) { 
       updates++; 
       for (int i=0; i < propertyNames.length; i++) { 
        if ("updated_at".equals(propertyNames[i])) { 
         currentState[i] = new Timestamp(Calendar.getInstance().getTime().getTime()); 
         return true; 
        } 
       } 
      } 
      return false; 
     } 

     public boolean onLoad(Object entity, 
           Serializable id, 
           Object[] state, 
           String[] propertyNames, 
           Type[] types) { 
      if (entity instanceof SystemConfiguration) { 
       loads++; 
      } 
      return false; 
     } 

    // This method is called when Entity object gets created. 
     public boolean onSave(Object entity, 
           Serializable id, 
           Object[] state, 
           String[] propertyNames, 
           Type[] types) { 

      if (entity instanceof SystemConfiguration) { 
       creates++; 
       for (int i=0; i<propertyNames.length; i++) { 
        if ("updated_at".equals(propertyNames[i])) { 
         state[i] = new Timestamp(Calendar.getInstance().getTime().getTime()); 
         return true; 
        } 
       } 
      } 
      return false; 
     } 

     public void afterTransactionCompletion(Transaction tx) { 
      if (tx.wasCommitted()) { 
       System.out.println("Creations: " + creates + ", Updates: " + updates +", Loads: " + loads); 
      } 
      updates=0; 
      creates=0; 
      loads=0; 
     } 
+0

Не понимаю ваш вопрос, но с помощью флеш-режиме по умолчанию сеанса ('AUTO'), сеанс сбрасывается, когда: 1) transaction.commit называется 2) запрос выполняется –

+0

Есть ли способ чтобы лица сохранялись? я имею в виду, чтобы не быть покрасневшим после выполнения запроса? –

+0

Могу сказать, что я делаю выбор, он возвращает список, который затем обрабатывает его, и после этого я обновляю его в БД, моя проблема в том, что спящий режим отмечает все сущности как грязные, потому что в persistanceContext сессии нет ничего –

ответ

1

Hibernate смоет, когда вы говорите его и, когда текущая транзакция является «закрытой» (как правило, когда DB-соединение каким-то образом возвращается в пул).

Таким образом, ответ на ваш вопрос зависит от того, какую структуру вы используете. С помощью Spring сеанс очищается, когда возвращается внешний метод @Transactional.

Ваше «решение» выше не будет работать долгое время, так как оно никогда не закрывает сеанс. Пока он возвращает результат, он будет терять соединение с базой данных, поэтому после нескольких вызовов у вас закончится соединение.

Также ваш вопрос не имеет смысла. SELECT не изменяет объекты, поэтому им не нужно «сохранять» до того, как вы их измените.

После изменения их в updateConfigurations(), Hibernate может не записывать их в базу данных сразу и просто обновлять кеш.

В конце концов, если вы все правильно настроили, Spring проведет транзакцию, и это приведет к сбросу кеша. Но когда вы используете Spring, вы никогда не должны создавать открытые и закрытые сеансы, потому что это будет бесполезно с тем, что делает Spring.

+0

Ваше объяснение действительно хорошее, но как я могу избежать этой утечки?, Дело в том, что я хочу, чтобы объекты, которые я выбрал в getListConfigurations(), оставались в сеансе (спящий режим кеша), а затем, когда я вызываю updateConfigurations(), спящий режим будет который может сравниться с его кешем, и это приведет к 1 обновлению, а не 100 (подразумевая, что мой выбранный список содержит 100 объектов) –

+0

Почему вы ожидаете только 1 обновления? –

+0

Потому что я изменяю только один объект из своего списка, поэтому я ожидаю, что этот спящий режим будет выглядеть в кеше, который изменил объект, а затем обновил только этот. –

Смежные вопросы