Domanda

Saluti Sto sviluppando un non-WebApplication utilizzando Primavera + Hibernate. La mia domanda è come la HibernateDaoSupport gestisce lazy-carico, perché dopo una chiamata fare DAO, la sessione viene chiusa.

Date un'occhiata al seguente pseudo-codice:

DAO è come:

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

modello di dominio è come:

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

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

Nella domanda ottengo DAO da app-contesto e voglio seguendo operations.Is questo possibile a che fare con lazy-caricamento perché per quanto ne so, dopo ogni metodo (getFamilyById (), getSubFamily ()) la sessione viene chiusa.

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();
È stato utile?

Soluzione

  

La mia domanda è come la HibernateDaoSupport gestisce lazy-carico, perché dopo una chiamata a DAO, la sessione viene chiusa.

I DAO non creano / chiudere una sessione per ogni chiamata, non sono responsabili di questo e questo di solito è fatto con il " Session Open in vista " modello (primavera fornire un filtro o un intercettore per questo). Ma questo è per le applicazioni web.

In un'applicazione un'altalena, una soluzione è quella di utilizzare lunga sessione . Dovrete decidere punti ben definiti in cui per chiudere la sessione per liberare la memoria. Per le applicazioni di piccole dimensioni, questo di solito è semplice e funziona. Per i più grandi (cioè le applicazioni della vita reale), la soluzione giusta è quella di utilizzare una seduta al telaio / telaio interno / dialogo. E 'più difficile da gestire, ma scalerà.

Alcune discussioni che si potrebbe desiderare di leggere:

Altri suggerimenti

Se si sta già utilizzando primavera si può fare uso del proprio Transaction-dichiarazione. L'utilizzo di questo si è in grado di dichiarare una transazione per un metodo specifico. Ciò mantiene il Sessio aperta per il tx completa.

dichiarare l'operazione pointcut

  <!-- 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>

Ora si può fare questo pigro mantenendo la sessione aperta per il metodo completo.

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

capitolo 9 di Springs Tx Riferimento per ulteriori dettagli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top