2011-01-15 14 views
17

Non sono sicuro quale sia il modo migliore per iniettare l'istanza di sessione di Hibernate nelle classi DAO utilizzando Spring3. Non sto usando il supporto di Spring's Hibernate Template per questo, quindi ecco il codice che ho nella classe DAO.Il modo migliore per iniettare la sessione di sospensione entro la primavera 3

public void setSessionFactory(SessionFactory sessionFactory){ 
    this.sessionFactory=sessionFactory; 
} 


public SessionFactory getSessionFactory(){ 
    log.info("Returning a refrence to the session instance"); 
    if(sessionFactory==null){ 
     log.error("Not able to find any associated session"); 
     throw new RuntimeException("Not able to find any associated session"); 
    } 
    return sessionFactory; 
} 

Di seguito si riporta il codice per l'iniezione di sessione a questo metodo

<bean id="genericSessionFactory" class="HibernateSessionFactory" 
     factory-method="getSessionfactory" scope="prototype/> 

Non sono sicuro se questo è il modo migliore per farlo iniezione SessionFactory dal momento che non vogliamo usare primavera Modello per il nostro progetto. Quindi qualsiasi altro suggerimento per il miglioramento sarà molto utile.

+0

Come state configurando il 'SessionFactory' stesso? – skaffman

+0

Usando Hibernate Standard modo una classe HibernateUtil leggendo varie proprietà e file cfg dal classpath –

risposta

20

Il Spring Reference suggests this usage:

public class ProductDaoImpl implements ProductDao { 

    private SessionFactory sessionFactory; 

    public void setSessionFactory(SessionFactory sessionFactory) { 
     this.sessionFactory = sessionFactory; 
    } 

    public Collection loadProductsByCategory(String category) { 
     return this.sessionFactory.getCurrentSession() 
       .createQuery(
        "from test.Product product where product.category=?") 
       .setParameter(0, category) 
       .list(); 
    } 
} 

In questo modo le vostre classi non hanno alcun dipendenze per Spring, è sufficiente utilizzare Hibernate pianura.

+0

Questo è quello che sto facendo ho una classe DAO generica dove ho tutti i metodi di persistenza generici e sto iniettando Hibernate Session factory nella classe DAO, ma invece di usare la classe Spring Hibernate SessionFactory Util sto usando la mia implosation.So sembra di essere sulla strada giusta .. –

+0

Non mi piace iniettare SessionFactory, dal momento che è una PITA a prendere in giro la Session e fare asserzioni su di essa in un test unitario. Non è possibile iniettare Session invece di SessionFactory? –

+0

@BastianVoigt è una domanda a parte. sentiti libero di chiedere. ma la risposta breve è: ciò sarebbe possibile solo se la classe del repository ha un ambito diverso da Singleton o se la sessione è un bean che è un proxy con scope.Entrambi mi sembrano pericolosi –

19

Stai complicando troppo questo.

Si prega di non utilizzare quel terribile modello HibernateUtil che continua a comparire nella documentazione di Hibernate. Spring offre un modo molto più bello di configurare un Hibernate SessionFactory - il LocalSessionFactoryBean (see docs for example usage).

LocalSessionFactoryBean produce un oggetto SessionFactory, che è possibile iniettare come proprietà nei bean DAO.

La primavera è felice per voi di non utilizzare HibernateDaoSupport e HibernateTemplate - c'è un section of the docs che spiega come farlo bene.

+0

Grazie per il puntatore del documento e devo dire userà Spring's LocalSessionFactoryBean per la gestione della creazione di Session factory e che utilizzerà il mio pattern DAO generico per utilizzare SessionFactory creato da LocalSessionFactoryBean –

+1

SO dovrebbe avere la possibilità di contrassegnare più risposte come accettate. –

22

Una combinazione di post di Skaffman e Sean e l'uso di annotazioni.

Dao

@Respository("productDao") 
public class ProductDaoImpl implements ProductDao { 

    @Autowired 
     private SessionFactory sessionFactory; 

      public Collection loadProductsByCategory(String category) { 
        return this.sessionFactory.getCurrentSession() 
         .createQuery(
          "from test.Product product where product.category=?") 
         .setParameter(0, category) 
         .list(); 
     } 
} 

XML

<beans> 

    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> 
    <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/> 
    <property name="username" value="sa"/> 
    <property name="password" value=""/> 
    </bean> 

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="myDataSource"/> 
    <property name="mappingResources"> 
     <list> 
     <value>product.hbm.xml</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <value> 
     hibernate.dialect=org.hibernate.dialect.HSQLDialect 
     </value> 
    </property> 
    </bean> 

</beans> 
+0

puoi pubblicare una configurazione java equivalente – rohanagarwal

11

Il modo consigliabile di usare Hibernate è attraverso JPA (hibernate-EntityManager):

@PersistenceContext 
private EntityManager entityManager; 

e nella applicationContext.xml:

<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="yourUnitName" /> 
    <property name="dataSource" ref="dataSource" /> <!-- needs a data source bean --> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="databasePlatform" value="${hibernate.dialect}" /> 
     </bean> 
    </property> 
</bean> 



<bean id="transactionManager" 
    class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

E avrete bisogno di un META-INF/persistence.xml

Problemi correlati