JdbcTemplate query close database connection

我们两清 提交于 2019-12-03 06:42:47

Actually, I have had that same issue recently...

After debugging trough the Hibernate code, I noticed Hibernate 4 calls HibernateJpaDialect.releaseConnection at some point. Comments before suggest that it's only to release the connection, but not to close it since it's the connection used by the transactional context. However, that releaseConnection method does in fact call JdbcUtils.closeConnection(con). The HibernateJpaDialect class responsible is actually part of the spring framework, not hibernate.

In the end, this issue is reported by Spring as a bug (SPR-10395) and should be fixed in release 3.2.3 or above. So in the end, you can use Hibernate 4.2 but you'll have to upgrade spring (orm) in that case:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>3.2.3</version>
</dependency>

I think that there is a bug in hibernate. I changed

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>4.2.5.Final</version>
</dependency>

to

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>4.1.12.Final</version>
</dependency>

and it works.

Comparison of 2 different version of HibernateJpaDialect from spring-orm artifact. Thanks to @Kevin Chabot for pointing this out:

HibernateJpaDialect (spring-orm ver 3.1.4)

public void releaseConnection(Connection con) {
    JdbcUtils.closeConnection(con);
}

HibernateJpaDialect (spring-orm ver 3.2.8)

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

Switching to spring-orm 3.2.3+ solves this problem. Be careful to include spring-orm in your pom.xml explicitly. The common mistake is when pom.xml contains only spring-data and fetches spring-orm thru transitive dependency from spring-data - and than it may be in wrong version.

First of all make sure that you are using the same DataSource for JPA as for your JdbcTemplate. Next wire the DataSource to the JpaTransactionManager.

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

This will make the transaction managed by the same transaction manager (you should only have one transaction manage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!