Ленивая загрузка с Spring HibernateDaoSupport? - PullRequest
1 голос
/ 27 января 2010

Приветствую. Я разрабатываю не веб-приложение, используя Spring + Hibernate. Мой вопрос заключается в том, как HibernateDaoSupport обрабатывает отложенную загрузку, потому что после вызова DAO сеанс закрывается.

Взгляните на следующий псевдо-код:

DAO это как:

CommonDao extends HibernateDaoSupport{
 Family getFamilyById(String id);
 SubFamily getSubFamily(String familyid,String subfamilyid);
}

Доменная модель похожа на:

Family{
 private List<SubFamily> subfamiles;
 public List<SubFamily> getSubFamiles();
}

SubFamily{
 private Family family; 
 public Family getFamily();
}

В приложении я получаю DAO из контекста приложения и хочу выполнить следующие операции. Это возможно сделать с отложенной загрузкой, поскольку AFAIK после каждого метода (getFamilyById (), getSubFamily ()) сеанс закрывается.

CommonDAO dao=//get bean from application context;
Family famA=dao.getFamilyById(familyid);
//
//Do some stuff
List<SubFamily> childrenA=fam.getSubFamiles();

SubFamily asubfamily=dao.getSubFamily(id,subfamilyid);
//
//Do some other stuff
Family famB=asubfamily.getFamily();

Ответы [ 2 ]

3 голосов
/ 27 января 2010

У меня вопрос, как HibernateDaoSupport обрабатывает отложенную загрузку, потому что после вызова DAO Сессия закрывается.

DAO не создают / закрывают сеанс для каждого вызова, они не несут ответственности за это, и обычно это делается с использованием шаблона " Открыть сеанс в представлении " (Spring предоставляет фильтр или перехватчик для этого). Но это для веб-приложений.

В свинг-приложении одним из решений является использование длинного сеанса . Вам нужно будет решить четко определенные точки, в которых можно закрыть сеанс, чтобы освободить память. Для небольших приложений это обычно просто и будет работать. Для больших (то есть реальных приложений) правильным решением является использование одного сеанса на кадр / внутренний кадр / диалог. Сложнее управлять, но будет масштабироваться.

Некоторые темы, которые вы можете прочитать:

2 голосов
/ 27 января 2010

Если вы уже используете Spring, вы можете использовать его декларацию транзакции. Используя это, вы можете объявить транзакцию для определенного метода. Это сохраняет Sessio открытым для полной передачи.

Объявление точки транзакции

  <!-- this is the service object that we want to make transactional -->
  <bean id="SomeService" class="x.y.service.SomeService"/>

  <tx:advice id="txAdvice" transaction-manager="txManager">
    <!-- the transactional semantics... -->
    <tx:attributes>
      <!-- all methods starting with 'get' are read-only -->
      <tx:method name="get*" read-only="true"/>
      <!-- other methods use the default transaction settings (see below) -->
      <tx:method name="*"/>
    </tx:attributes>
  </tx:advice>

  <!-- ensure that the above transactional advice runs for any execution
      of an operation defined by the FooService interface -->
  <aop:config>
    <aop:pointcut id="MyServicePointcut" expression="execution(* x.y.service.SomeService.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="SomeServiceOperation"/>
  </aop:config>

  <bean id="txManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
  </bean>

Теперь вы можете сделать это лениво, оставив сессию открытой для полного метода.

public class SomeService()
{
  public Family getFamily()
  {
    Family famA=dao.getFamilyById(familyid);
    //Do some stuff
    List<SubFamily> childrenA=fam.getSubFamiles();
    SubFamily asubfamily=dao.getSubFamily(id,subfamilyid);
    //Do some other stuff
    return asubfamily.getFamily();
  }
}

См. Глава 9 Ссылка Springs Tx для получения дополнительной информации.

...