Lazy-carico con Spring HibernateDaoSupport?
-
23-09-2019 - |
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();
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:
- hibernate LazyInitializationException nella ricca applicazione client
- Primavera / Hibernate sostegno lunga sessione o migliori pratiche?
- Tenere sessione Hibernate aperta nel client di oscillazione? (questo è IMHO il più interessante, soprattutto # 9)
- Hibernate e swing demo app
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.