Spring + Hibernate不会自动打开会话 [英] Spring + Hibernate don't open automatically the session
问题描述
我正在使用以下架构在Spring应用程序中开发Hibernate DAO:
我有一个PersonDAO接口,我声明了我想要的CRUD方法,然后我创建了一个实现此接口的具体类PersonDAOImpl,这个接口是这样的:
package org.andrea.myexample.HibernateOnSpring.dao;
导入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 {
//工厂每个会话的休眠时间:
private static SessionFactory SessionFactory的;
//每个代码段的代码设置器SessionFactory:
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
System.out.println(Ho iniettato la SessionFactory:+ sessionFactory);
/ ** CREATE CRUD操作:
* Aggiunge un nuovo记录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);
返回personID;
}
}
然后我()方法来测试它是如何工作的。
问题是,当我执行MainApp时尝试在数据库中插入新记录我在堆栈跟踪中获得以下错误消息:
INFO:Using DataSource [org。 Hibernate SessionFactory的HibernateTransactionManager
中的SessionFactory:org.hibernate.internal.SessionFactoryImpl@34a8a14b
Contesto recuperato:org.springframework.context.support.ClassPathXmlApplicationContext @ 70501e4e:启动日期[2009年3月9日10:02:37 CET 2013];上下文层次结构的根
Creato persona1:org.andrea.myexample.HibernateOnSpring.entity.Person@2d35bcd7
线程main中的异常java.lang.ClassCastException:org.andrea.myexample.HibernateOnSpring.dao。 PersonDAOImpl2 $$ EnhancerByCGLIB $$ d0c4a932无法转换为org.andrea.myexample.HibernateOnSpring.dao.PersonDAO
位于org.andrea.myexample.HibernateOnSpring.MainApp.main(MainApp.java:26)
似乎找不到Session对象,现在我有一个疑问:我知道Spring会自动打开和关闭每个@Transactional方法的会话,但它似乎不工作!!!
相反,如果我打电话给该方法时显式打开一个新的会话,它工作那么...以这种方式:
@Transactional(readOnly = false)
public Integer addPerson(Person p) {
System.out.println(Inside addPerson());
会话会话= sessionFactory.openSession();
交易tx = null;
Integer personID = null;
尝试{
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;
}
但我认为我可以说Spring会自动打开输入方法时输入Session并退出时关闭
这是我的XML配置文件:
<?xml version =1.0encoding =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 =dataSourceclass =org.apache.commons.dbcp.BasicDataSource>
< property name =driverClassNamevalue =com.mysql.jdbc.Driver/>
< property name =urlvalue =jdbc:mysql:// localhost:3306 / SpringTestDb/>
< property name =usernamevalue =root/>
< property name =passwordvalue =MY_DB_PSWD/>
< property name =initialSizevalue =2/>
< property name =maxActivevalue =5/>
< / bean>
< bean id =sessionFactoryclass =org.springframework.orm.hibernate4.LocalSessionFactoryBean>
< property name =dataSourceref =dataSource/>
< property name =packagesToScanvalue =org.andrea.myexample.HibernateOnSpring.entity/>
< property name =hibernateProperties>
<道具>
< prop key =hibernate.dialect> org.hibernate.dialect.MySQLDialect< / prop>
< prop key =hibernate.hbm2ddl.auto> update< / prop>
< prop key =hibernate.show_sql> false< / prop>
< /道具>
< / property>
< / bean>
< bean id =transactionManagerclass =org.springframework.orm.hibernate4.HibernateTransactionManager>
< property name =sessionFactoryref =sessionFactory/>
< / bean>
< tx:注解驱动的事务管理器=transactionManager/>
< bean id =personDAOImplclass =org.andrea.myexample.HibernateOnSpring.dao.PersonDAOImpl2>
< property name =sessionFactoryref =sessionFactory/>
< / bean>
<! - Register @Autowired annotation - >
< bean class =org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor/>
< / beans>
有人可以帮我吗?
Tnx
Andrea
您需要为您的DAO使用接口或重新配置代理机制以使用类。
I am developing an Hibernate DAO in a Spring application using the following architecture:
I have a PersonDAO interface in which I declare the CRUD method that I want and then I create a concrete class PersonDAOImpl that implement this interface, this one:
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;
}
}
And then I have create a MainApp class conteining the main() method to test how it work.
The problem is that when I execute the MainApp when I try to insert a new record in the database I obtain the following error message in the stacktrace:
INFO: Using DataSource [org.apache.commons.dbcp.BasicDataSource@446adaa2] of Hibernate SessionFactory for HibernateTransactionManager
Ho iniettato la SessionFactory: org.hibernate.internal.SessionFactoryImpl@34a8a14b
Contesto recuperato: org.springframework.context.support.ClassPathXmlApplicationContext@70501e4e: startup date [Sat Mar 09 10:02:37 CET 2013]; root of context hierarchy
Creato persona1: org.andrea.myexample.HibernateOnSpring.entity.Person@2d35bcd7
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)
Seems like it don't find the Session object and now I have a doubt: I know that Spring open and close automatically the Session for every @Transactional method but it seems don't work !!!
On the contrary, if I explicitly open a new session when I call the method, it work well...in this way:
@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;
}
But I think that I can say Spring to automatically open the Session when enter in the method and close it when exit
This is my XML configuration file:
<?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>
Someone can help me?
Tnx
Andrea
You need either use interfaces for your DAO or reconfigure the proxy mechanism to use classes.
这篇关于Spring + Hibernate不会自动打开会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!