使用Spring HibernateDaoSupport进行延迟加载?

时间:2010-01-27 06:41:12

标签: java hibernate spring orm lazy-loading

问候我正在使用Spring + Hibernate开发一个非Web应用程序。 我的问题是HibernateDaoSupport如何处理延迟加载,因为在调用DAO之后,会话关闭。

看一下psuedo-code:

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();
}

在应用程序中,我从app-context获取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 个答案:

答案 0 :(得分:3)

  

我的问题是HibernateDaoSupport如何处理延迟加载,因为在调用DAO之后,会话已关闭。

DAO不会为每次调用创建/关闭一个Session,他们不对此负责,这通常使用“Open Session in View”模式(Spring为此提供过滤器或拦截器)来完成。但这适用于网络应用。

在swing应用中,一种解决方案是使用long session。您必须决定关闭会话以释放内存的明确定义的点。对于小型应用程序,这通常很简单并且可以工作。对于更大的(即现实生活中的应用程序),正确的解决方案是每帧使用一个会话/内部框架/对话框。管理起来比较困难,但会扩展。

您可能想要阅读的一些主题:

答案 1 :(得分:2)

如果您已经使用Spring,则可以使用其Transaction-Declaration。使用此功能,您可以为特定方法声明事务。这使Sessio保持开放状态为完整的tx。

声明交易切入点

  <!-- 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();
  }
}

有关详细信息,请参阅Springs Tx参考的Chapter 9