2010-01-27 5 views
1

Salutations Je développe une application non-web en utilisant Spring + Hibernate. Ma question est de savoir comment HibernateDaoSupport gère le chargement paresseux, car après un appel DAO, la session est fermée.Chargement paresseux avec Spring HibernateDaoSupport?

Jetez un oeil à la suite psuedo-code:

OAC est comme:

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

modèle de domaine est comme:

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

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

Dans l'application, je reçois DAO à partir app-contexte et que vous voulez suivre des opérations.Est-ce possible de faire avec paresseux-chargement parce que AFAIK après chaque méthode (getFamilyById(), getSubFamily()) la session est fermée.

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

Répondre

3

Ma question est de savoir comment HibernateDaoSupport gère le chargement différé, car après un appel à DAO, la session est fermée.

Les OTI ne créent pas/fermer une session pour chaque appel, ils ne sont pas responsables de cela et cela se fait généralement en utilisant le modèle « Open Session in View » (printemps fournir un filtre ou un intercepteur pour cela). Mais c'est pour les applications web.

Dans une application swing, une solution consiste à utiliser long session. Vous devrez décider des points bien définis auxquels fermer la session pour libérer de la mémoire. Pour les petites applications, cela est généralement simple et fonctionnera. Pour de plus grandes applications (c'est-à-dire réelles), la bonne solution consiste à utiliser une session par image/image/boîte de dialogue interne. C'est plus difficile à gérer mais à l'échelle.

Certains sujets que vous pouvez lire:

2

Si vous utilisez déjà Spring, vous pouvez utiliser sa déclaration de transaction. En utilisant cela, vous êtes en mesure de déclarer une transaction pour une méthode spécifique. Cela maintient le Sessio ouvert pour le tx complet.

Déclarez l'opération 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> 

Maintenant, vous pouvez le faire paresseux garder la session ouverte pour la méthode complète.

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

Voir Chapter 9 Springs Tx Référence pour plus de détails.

Questions connexes