无法为事务打开休眠会话/无法打开连接 [关闭]

Posted

技术标签:

【中文标题】无法为事务打开休眠会话/无法打开连接 [关闭]【英文标题】:Could not open Hibernate Session for transaction / Cannot open connection [closed] 【发布时间】:2013-08-09 08:35:37 【问题描述】:

在我的应用程序中,我有一个模块,用于在数据库中搜索用户并将他们的信息显示在 jsp 内的表中。我只是在我的应用程序中设置了 Spring Security。我能够从登录页面连接到数据库,但由于某种原因,我的 DAO 的 CRUD 操作(在本例中为搜索)都不起作用。

谢谢,如果我能提供更多信息,请告诉我。

这是我的大部分堆栈跟踪。

    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Cannot open connection
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
        org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

...

org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Cannot open connection
    org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:596)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
    org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    $Proxy8.searchEntity(Unknown Source)
    arlua.controller.SearchUserController.mySearchMethod(SearchUserController.java:35)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source

...

    org.hibernate.exception.GenericJDBCException: Cannot open connection
        org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
        org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
        org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52)
        org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449)
        org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
        org.hibernate.jdbc.BorrowedConnectionProxy.invoke(BorrowedConnectionProxy.java:74)
        $Proxy14.getTransactionIsolation(Unknown Source)

...

    java.sql.SQLException: invalid arguments in call
        oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
        oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
        oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
        oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:236)
        oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:414)
        oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
        oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
        oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
        java.sql.DriverManager.getConnection(Unknown Source)
        java.sql.DriverManager.getConnection(Unknown Source)
        org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:173)
        org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:164)
        org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:149)
        org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:119)
        org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
        org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
        org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
        org.hibernate.jdbc.BorrowedConnectionProxy.invoke(BorrowedConnectionProxy.java:74)
        $Proxy14.getTransactionIsolation(Unknown Source)
        org.springframework.jdbc.datasource.DataSourceUtils.prepareConnectionForTransaction(DataSourceUtils.java:190)
        org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:508)
        org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
        org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
        org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
        org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        $Proxy8.searchEntity(Unknown Source)
        arlua.controller.SearchUserController.mySearchMethod(SearchUserController.java:35)
        sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        java.lang.reflect.Method.invoke(Unknown Source)
        org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
        org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
        org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
        org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
        org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
        org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
        org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
        org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)

SearchUserController 类

package arlua.controller;

import java.util.List;

import arlua.dao.TableEntityFetchDao;
import arlua.exception.ImproperUserSearchException;
import arlua.exception.SearchStringTooShortException;
import arlua.helper.BuildUserTables;
import arlua.service.SearchCriteria;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

@Controller
@SessionAttributes
public class SearchUserController 

    private @Autowired @Qualifier("userInfoDaoImpl") TableEntityFetchDao userInfoDao;

    List<?> searchList;
    String error;

    @RequestMapping(value = "/search_user", method = RequestMethod.POST)
    public String mySearchMethod(@ModelAttribute("search_criteria") SearchCriteria search)

        error = "";
        try
            if(search.getInput() != null)
                searchList = userInfoDao.searchEntity(search.getInput());
        
        catch(SearchStringTooShortException e1)
            error = "Search criteria is too short. Be more specific.";
        
        catch(ImproperUserSearchException e2)
            error = "Specify either an Id or first and last name.";
        

        return "redirect:search_user";
    

    @RequestMapping("/search_user")
    public ModelAndView mySuccessMethod()
        ModelAndView model = new ModelAndView("search_user");

        if(searchList != null)
            if(searchList.size() == 0)
                error = "Search returned no results.";
            else
                model.addObject("searchTable", BuildUserTables.buildSearch(searchList));
        

        return model;
    


UserInfoDaoImpl 类

package arlua.dao.impl;

import arlua.dao.TableEntityFetchDao;
import arlua.exception.ImproperUserSearchException;
import arlua.exception.SearchStringTooShortException;
import arlua.tables.UserInfoTable;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class UserInfoDaoImpl implements TableEntityFetchDao

    @Autowired
    private SessionFactory sessionFactory;

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

    public void saveEntity(Object userInfo) 
        this.sessionFactory.getCurrentSession().save((UserInfoTable)userInfo);
    

    public UserInfoTable getEntity(Object user_id) 
        return (UserInfoTable)this.sessionFactory.getCurrentSession().
            get(UserInfoTable.class, (String)user_id);
    

    public void updateEntity(Object userInfo) 
        this.sessionFactory.getCurrentSession().update((UserInfoTable)userInfo);
    

    public void deleteEntity(Object userInfo) 
        this.sessionFactory.getCurrentSession().delete((UserInfoTable)userInfo);
    

    public List<?> getAllEntities() 
        return this.sessionFactory.getCurrentSession().createQuery
            ("FROM UserInfoTable").list();
    

    public List<?> searchEntity(String search) throws SearchStringTooShortException, ImproperUserSearchException
        //This search supports input of a user's seid OR a first and last name.
        if(search.length() < 3)
            throw new SearchStringTooShortException();
        

        Session s = this.sessionFactory.getCurrentSession();
        List<?> searchList = new ArrayList();

        //Searches for similar users with matching SEIDs.
        if(search.matches("^[a-zA-Z0-9]*[0-9]+[a-zA-Z0-9]*$"))
            searchList = s.createQuery
                //("FROM UserInfoTable").list();
                ("FROM UserInfoTable WHERE UPPER(user_id) LIKE UPPER('%" + search + "%')").list();

        
        //Searches for similar users with a matching first and last name.
        //If the search contains more than 2 arguments, an exception will be thrown.
        else if(search.length() >= 3)
            String[] searchParts = search.split(" ");
            if(searchParts.length != 2)
                throw new ImproperUserSearchException();
            searchList = s.createQuery
                ("FROM UserInfoTable WHERE UPPER(first_name) LIKE UPPER('%" + searchParts[0] + "%') " +
                        "AND UPPER(last_name) LIKE UPPER('%" + searchParts[1] + "%')").list();
        
        else
            throw new ImproperUserSearchException();
        

        return searchList;
    

application-context.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />

    <bean id="serverDatasource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>oracle.jdbc.driver.OracleDriver</value>
        </property>
        <property name="url">
            <value>url</value>
        </property>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
        <property name="targetDataSource" ref="serverDatasource"/>
        <property name="username"><value>unknown</value></property>
        <property name="password"><value>unknown</value></property>
    </bean>

    <!--
    <bean id="propertyPlaceholderConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="ignoreUnresolvablePlaceholders" value="true"/>
    </bean>
    -->

    <bean id="mySessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="mappingLocations">
            <list>
                <value>WEB-INF/mapping/user_info.hbm.xml</value>
                <value>WEB-INF/mapping/login.hbm.xml</value>
                <value>WEB-INF/mapping/linked_accounts.hbm.xml</value>
                <value>WEB-INF/mapping/application_instance.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <property name="dataSource" ref="serverDatasource"/>
    </bean>

    <bean id = "userInfoDaoImpl" class="arlua.dao.impl.UserInfoDaoImpl">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <bean id = "loginDaoImpl" class="arlua.dao.impl.LoginDaoImpl">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <bean id = "linkedAccountsDaoImpl" class="arlua.dao.impl.LinkedAccountsDaoImpl">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <bean id = "applicationInstanceDaoImpl" class="arlua.dao.impl.ApplicationInstanceDaoImpl">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <bean id = "roleDaoImpl" class="arlua.dao.impl.RoleDaoImpl">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <bean id = "applicationApprovalDaoImpl" class="arlua.dao.impl.ApplicationApprovalDaoImpl">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <bean id = "userDaoImpl" class="arlua.dao.impl.UserDaoImpl"/>

    <!--  *************  TRANSACTION MANAGEMENT USING AOP **************** -->

    <bean id="myTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>    
    </bean>

    <aop:config>
        <aop:pointcut id="allMethods" expression="execution(* arlua.dao.TableEntityFetchDao.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods"/>
    </aop:config>

    <tx:advice id="txAdvice" transaction-manager="myTransactionManager">
        <tx:attributes>
            <tx:method name="saveEntity"
                propagation = "REQUIRES_NEW"
                isolation = "READ_COMMITTED"
                rollback-for = "Exception"/>
            <tx:method name="updateEntity"
                propagation = "REQUIRES_NEW"
                isolation = "READ_COMMITTED"
                rollback-for = "Exception"/>
            <tx:method name="getEntity"
                propagation = "REQUIRES_NEW"
                isolation = "READ_COMMITTED"
                rollback-for = "Exception"/>
            <tx:method name="getAllEntities"
                propagation = "REQUIRES_NEW"
                isolation = "READ_COMMITTED"
                rollback-for = "Exception"/>
            <tx:method name="searchEntity"
                propagation = "REQUIRES_NEW"
                isolation = "READ_COMMITTED"
                rollback-for = "Exception"/>
        </tx:attributes>
    </tx:advice>

</beans>

【问题讨论】:

你能把它缩减到只有相关部分吗?这太长了,没有很好的机会引起任何关注。见sscce.org 我删除了 LoginController 和安全上下文。同样,异常本身源于此行的 SearchUserController:searchList = userInfoDao.searchEntity(search.getInput()); &lt;property name="url"&gt; &lt;value&gt;url&lt;/value&gt; &lt;/property&gt; 是正确的服务器 url 吗?!? @Bellabax 是的。在我的实际 xml 文件中,我有真正的 url。当我在这里发布它时,我只是在那里放置了一个占位符。我已经能够使用我的登录控制器中的 url、用户名和密码成功地在 Spring Security 中验证数据库登录。 如果将 SearchUserController 标记为事务性会发生什么。 ... @Transactional 公共类 SearchUserController ... ?? 【参考方案1】:

java.sql.SQLException: invalid arguments in call 表示连接到数据库时出现问题,对 URL/auth 问题进行处理:查看堆栈跟踪,您没有通过 UserCredentialsDataSourceAdapter(您的 id="datasource")获得连接,而是使用 DriverManagerDataSourceid="serverDatasource"):简而言之您正在尝试在不使用用户名/密码的情况下进行连接。

在 sessionFactory bean 中创建线:&lt;property name="dataSource" ref="dataSource"/&gt; 而不是:&lt;property name="dataSource" ref="serverDatasource"/&gt;

【讨论】:

谢谢!当我添加 Spring Security 时,我完全错过了这一点。我在登录控制器中使用 UserCredentialsDataSourceAdapter 进行身份验证,但我的 SessionFactory 使用的是 DriverManagerDataSource。

以上是关于无法为事务打开休眠会话/无法打开连接 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

视图中的休眠打开会话:每个请求的事务?

Spring Hibernate - 无法为当前线程获取事务同步会话

spring boot 1.5.1.RELEASE 问题与休眠会话工厂创建有关

尝试运行 Ubuntu 时出现 VirtualBox 错误“无法打开会话”[关闭]

休眠中的多租户数据库

win2012系统如何关闭休眠