Spring JdbcTemplate查询关闭数据库连接
我在hibernate中使用jpa。我有以下方法:Spring JdbcTemplate查询关闭数据库连接,spring,hibernate,jpa,jdbctemplate,Spring,Hibernate,Jpa,Jdbctemplate,我在hibernate中使用jpa。我有以下方法: @Transactional public void myMethod(){ ... firstJDBCTemplateQuery(); secondJDBCTemplateQuery(); ... } firstJDBCTemplateQuery可以工作,但它会关闭到数据库的连接。执行第二个secondjdbtempoleQuery时 java.sql.SQLException:连接已关闭异常 是什么原因造成的 org.springfra
@Transactional
public void myMethod(){
...
firstJDBCTemplateQuery();
secondJDBCTemplateQuery();
...
}
firstJDBCTemplateQuery
可以工作,但它会关闭到数据库的连接。执行第二个secondjdbtempoleQuery
时
java.sql.SQLException:连接已关闭异常
是什么原因造成的
org.springframework.transaction.TransactionSystemException:无法回滚JPA事务…
我的配置:
编辑
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="packagesToScan" value="com.emisoft.ami.user.domain" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<jpa:repositories base-package="com.emisoft.ami.user.repository"
entity-manager-factory-ref="emf" transaction-manager-ref="transactionManager" />
...
编辑调试结果:
Beigin事务启动时myMethod()
:
//////////////////////////////////
firstJDBCTemplateMethod
:
//////////////////////////////////
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL update
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [insert into users (username, password, enabled) values (?,?,?)]
DEBUG: org.springframework.jdbc.core.JdbcTemplate - SQL update affected 1 rows
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL query
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select id from groups where group_name = ?]
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
INFO : org.springframework.jdbc.support.SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
DEBUG: org.springframework.jdbc.support.SQLErrorCodesFactory - Looking up default SQLErrorCodes for DataSource [org.apache.commons.dbcp.BasicDataSource@150f6f]
WARN : org.springframework.jdbc.support.SQLErrorCodesFactory - Error while extracting database product name - falling back to empty error codes
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Connection is closed. ///This is the beginning of stacktrace which is located above.
/////////////////////////////////////////
secondJDBCTemplateMethod
:
////////////////////////////////////
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL update
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [insert into users (username, password, enabled) values (?,?,?)]
DEBUG: org.springframework.jdbc.core.JdbcTemplate - SQL update affected 1 rows
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL query
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select id from groups where group_name = ?]
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
INFO : org.springframework.jdbc.support.SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
DEBUG: org.springframework.jdbc.support.SQLErrorCodesFactory - Looking up default SQLErrorCodes for DataSource [org.apache.commons.dbcp.BasicDataSource@150f6f]
WARN : org.springframework.jdbc.support.SQLErrorCodesFactory - Error while extracting database product name - falling back to empty error codes
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Connection is closed. ///This is the beginning of stacktrace which is located above.
编辑
PaymentServiceContext
:
public class PaymentServiceContext {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"com/kulig/test/service/PaymentServiceTest-context.xml");
UserService userService = context.getBean(UserService.class);
///CREATE POJO OBJECTS credentials and p
...
userService.insert(credentials, p);
}
}
首先,确保JPA使用的数据源与JdbcTemplate使用的数据源相同。接下来将
数据源连接到JpaTransactionManager
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
<property name="dataSource" ref="dataSource" />
</bean>
这将使事务由同一个事务管理器管理(您应该只有一个事务管理器)我认为hibernate中存在错误。我更改了
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.5.Final</version>
</dependency>
org.hibernate
休眠实体管理器
4.2.5.最终版本
到
org.hibernate
休眠实体管理器
4.1.12.最终版本
事实上,我最近也遇到过同样的问题
在通过Hibernate代码进行调试之后,我注意到Hibernate 4在某个时候调用了HibernateJpaDialect.releaseConnection。之前的评论建议只释放连接,而不关闭连接,因为它是事务上下文使用的连接。然而,releaseConnection方法实际上调用了JdbcUtils.closeCon负责的HibernateAppDialect类实际上是spring框架的一部分,而不是hibernate
最后,Spring将此问题报告为一个bug(SPR-10395),应该在3.2.3版或更高版本中修复。因此,最终,您可以使用Hibernate 4.2,但在这种情况下,您必须升级Spring(orm):
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.3</version>
</dependency>
org.springframework
春季甲虫
3.2.3
比较spring orm工件的两个不同版本的HibernateAppDialect。
感谢@Kevin Chabot指出这一点:
HibernatePadialect(spring orm版本3.1.4)
HibernatePadialect(spring orm版本3.2.8)
切换到spring orm 3.2.3+
解决了这个问题。请注意在pom.xml中显式地包含spring orm。常见的错误是pom.xml只包含spring数据
,并通过从spring数据
中的传递依赖项获取spring orm
,而不是错误的版本。您能理解吗您能发布firstJDBCTemplateQuery
和secondJDBCTemplateQuery
code第一眼看到配置没有问题吗?您能发布第一个事务/周围方法的调试/跟踪信息吗?以及PaymentServiceContext
的代码吗?我添加了。只调用用户service.insert(..)
方法,我在我的帖子开头将其命名为myMethod()
),我认为org.springframework.orm.jpa.JpaTransactionManager
会自动找到数据源。我只有一个数据源,所以应该没有问题。我按照你说的做了,没有任何更改。只有当EntityManager使用的数据源相同时,才会检测到它。你能用你的完整配置更新你的问题吗(persistence.xml
和EntityManagerFactory
配置)。我添加了EntityManagerFactory
。我使用EntityManagerFactory
中的packagesToScan
属性,而不是persistence.xml
。升级spring应该允许您使用hibernate 4.2(见下文)
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.12.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.3</version>
</dependency>
public void releaseConnection(Connection con) {
JdbcUtils.closeConnection(con);
}
public void releaseConnection(Connection con) {
if (sessionConnectionMethod != null) {
// Need to explicitly call close() with Hibernate 3.x in order to allow
// for eager release of the underlying physical Connection if necessary.
// However, do not do this on Hibernate 4.2+ since it would return the
// physical Connection to the pool right away, making it unusable for
// further operations within the current transaction!
JdbcUtils.closeConnection(con);
}
}