2013-03-09 80 views
1

我使用下面的架构开发的Hibernate的DAO在Spring应用程序:Spring + Hibernate的不自动打开会话

我有,我宣布,我要的CRUD方法,然后一个的PersonDAO接口I创建一个具体类PersonDAOImpl实现此接口,这一个:

package org.andrea.myexample.HibernateOnSpring.dao; 

import org.andrea.myexample.HibernateOnSpring.entity.Person; 
import org.hibernate.SessionFactory; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Transactional; 

@Repository 
@Transactional 
public class PersonDAOImpl2 { 

    // Factory per la creazione delle sessioni di Hibernate: 
     private static SessionFactory sessionFactory; 

     // Metodo Setter per l'iniezione della dipendenza della SessionFactory: 
     public void setSessionFactory(SessionFactory sessionFactory) { 
      this.sessionFactory = sessionFactory; 
      System.out.println("Ho iniettato la SessionFactory: " + sessionFactory); 

     } 

     /** CREATE CRUD Operation: 
     * Aggiunge un nuovo record rappresentato nella tabella rappresentato 
     * da un oggetto Person 
     */ 
     @Transactional(readOnly = false) 
     public Integer addPerson(Person p) { 

      System.out.println("Inside addPerson()"); 
      System.out.println("Connessione aperta: " + sessionFactory.getCurrentSession().isOpen()); 
      System.out.println("E' connesa:" + sessionFactory.getCurrentSession().isConnected()); 

      Integer personID = personID = (Integer) sessionFactory.getCurrentSession().save(p); 

      return personID; 

     } 

} 

然后,我已创建一个MainApp类conteining的main()方法来测试它是如何工作的。

的问题是,当我执行MainApp当我尝试插入我得到的堆栈跟踪以下错误信息数据库的新纪录:

INFO: Using DataSource [[email protected]] of Hibernate SessionFactory for HibernateTransactionManager 
Ho iniettato la SessionFactory: [email protected] 
Contesto recuperato: org[email protected]70501e4e: startup date [Sat Mar 09 10:02:37 CET 2013]; root of context hierarchy 
Creato persona1: [email protected] 
Exception in thread "main" java.lang.ClassCastException: org.andrea.myexample.HibernateOnSpring.dao.PersonDAOImpl2$$EnhancerByCGLIB$$d0c4a932 cannot be cast to org.andrea.myexample.HibernateOnSpring.dao.PersonDAO 
    at org.andrea.myexample.HibernateOnSpring.MainApp.main(MainApp.java:26) 

好像也没有找到会议对象,现在我有一个疑问:我知道Spring为每个@Transactional方法自动打开和关闭会话,但它似乎不工作!

相反,如果我明确地打开一个新的会话时,我调用该方法,它工作得很好......这样:

@Transactional(readOnly = false) 
    public Integer addPerson(Person p) { 

     System.out.println("Inside addPerson()"); 

     Session session = sessionFactory.openSession(); 

     Transaction tx = null; 
     Integer personID = null; 

     try { 
      tx = session.beginTransaction(); 

      personID = (Integer) session.save(p); 
      tx.commit(); 
     } catch (HibernateException e) { 
      if (tx != null) 
       tx.rollback(); 
      e.printStackTrace(); 
     } finally { 
      session.close(); 
     } 

     return personID; 

    } 

但我认为,我可以说春天来自动打开会话时在输入方法,并关闭它,当退出

这是我的XML配置文件:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd   
     http://www.springframework.org/schema/tx 
     http://www.springframework.org/schema/tx/spring-tx-3.1.xsd "> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
     <property name="url" value="jdbc:mysql://localhost:3306/SpringTestDb" /> 
     <property name="username" value="root" /> 
     <property name="password" value="MY_DB_PSWD" /> 
     <property name="initialSize" value="2" /> 
     <property name="maxActive" value="5" /> 
    </bean> 

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="packagesToScan" value="org.andrea.myexample.HibernateOnSpring.entity" /> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
       <prop key="hibernate.hbm2ddl.auto">update</prop> 
       <prop key="hibernate.show_sql">false</prop> 
      </props> 
     </property> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

    <tx:annotation-driven transaction-manager="transactionManager"/> 

    <bean id="personDAOImpl" class="org.andrea.myexample.HibernateOnSpring.dao.PersonDAOImpl2" > 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

    <!-- Register @Autowired annotation --> 
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> 
</beans> 

有人能帮助我吗?

TNX

安德烈

+0

如何使用PersonDAOImpl2 – 2013-03-09 10:40:03

回答

1

你必须告诉春时 “打开” 会议。 准备好使用Spring实现,它在处理请求之前打开会话。

<mvc:interceptors> 
    <bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> 
     <property name="sessionFactory"> 
      <ref local="sessionFactory"/> 
     </property> 
    </bean> 
</mvc:interceptors>