Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法检索预先绑定的Hibernate会话-无法获取当前线程的事务同步会话_Java_Spring_Hibernate - Fatal编程技术网

Java 无法检索预先绑定的Hibernate会话-无法获取当前线程的事务同步会话

Java 无法检索预先绑定的Hibernate会话-无法获取当前线程的事务同步会话,java,spring,hibernate,Java,Spring,Hibernate,我正在用SpringMVC、SpringSecurity、SpringCore和hibernate创建一个web应用程序 但我总是从hibernate会话工厂得到这个非错误 它实际上抛出了HibernateException,但我在日志中看到它处于调试级别,我的应用程序实际上继续执行,没有问题 但我很想了解提出这一例外的原因 日志显示以下行 2016-08-29 13:34:55,310 DEBUG [sg.com.diamond.express.base.dao.impl.HibernateD

我正在用SpringMVC、SpringSecurity、SpringCore和hibernate创建一个web应用程序

但我总是从hibernate会话工厂得到这个非错误

它实际上抛出了HibernateException,但我在日志中看到它处于调试级别,我的应用程序实际上继续执行,没有问题

但我很想了解提出这一例外的原因

日志显示以下行

2016-08-29 13:34:55,310 DEBUG [sg.com.diamond.express.base.dao.impl.HibernateDAOImpl].[doExecute]([328]) [http-nio-8888-exec-4] - Could not retrieve pre-bound Hibernate session
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
    at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:325)
    at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308)
    at org.springframework.orm.hibernate4.HibernateTemplate.get(HibernateTemplate.java:418)
    at org.springframework.orm.hibernate4.HibernateTemplate.get(HibernateTemplate.java:411)
    at sg.com.diamond.express.base.dao.impl.BaseHibernateDaoImpl.findById(BaseHibernateDaoImpl.java:160)
    at sg.com.diamond.express.webadmin.service.impl.ClientProfileServiceImpl.searchByName(ClientProfileServiceImpl.java:48)
    at sg.com.diamond.express.webadmin.controller.impl.ClientController.home(ClientController.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.web.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:472)
    at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:409)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:146)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
这是我的密码

DAO级别

这是一个抽象级别,我创建它是为了尽量减少DAO的锅炉板代码的数量,不需要实现基本的c-r-u-d

BaseDAO接口

公共接口BaseDAO{
会话getCurrentSession();
M findById(ID)抛出异常;
列出findByCriteria(M标准)异常;
List listAll()引发异常;
ID saveObject(M object)抛出异常;
void saveOrUpdate(M对象)抛出异常;
querycreatequery(stringhql)抛出异常;
querycreatesqlquery(stringsql)抛出异常;
criteriacreatecriteria(类clazz)抛出异常;
List runQuery(查询查询)抛出异常;
列表运行查询(字符串sql)抛出异常;
}
BaseDAO实现

公共类BaseHibernateDaoImpl扩展了HibernateTemplate实现BaseDAO{
保护类模型类;
@凌驾
公共会话getCurrentSession(){
返回这个.getSessionFactory().getCurrentSession();
}
公共ID保存对象(M对象)引发异常{
试一试{
对象。setCreator(“批处理”);
setCreatedAt(新时间戳(new Date().getTime());
对象。setUpdater(“批处理”);
setUpdatedAt(新时间戳(new Date().getTime());
返回(ID)超级保存(对象);
}捕获(例外e){
记录器错误(例外直到getStackTraces(e),e);
抛出新的异常(e);
}
}
/**所有其他实施方法**/
SpringXML配置

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Data Source Configuration
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="targetDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@192.168.170.36:1521:EXPT2" />
        <property name="username" value="EXP_USER" />
        <property name="password" value="passw0rd" />
    </bean>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <property name="targetDataSource" ref="targetDataSource"/>
    </bean>

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Hibernate abstract session factory parent
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="baseSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" abstract="true">
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
            </props>
        </property>
    </bean>

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Hibernate entity configurations
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="expressSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" parent="baseSessionFactory">
        <property name="hibernateProperties">
            <props merge="true">
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
            </props>
        </property>
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingLocations" value="classpath*:hbm/express/*.hbm.xml"/>
    </bean>

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Transaction Management
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="expressSessionFactory"/>
    </bean>

    <aop:config>
        <aop:pointcut id="servicePointcut" expression="execution(* sg.com.diamond.express.webadmin.service.*.*.*(..))"/>
        <aop:advisor id="serviceTx" advice-ref="txAdvice" pointcut-ref="servicePointcut"/>
    </aop:config>

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*"      propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="true" />
            <tx:method name="search*"   propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="true" />
            <tx:method name="list*"     propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="true" />
            <tx:method name="is*"       propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="true" />
            <tx:method name="*"         propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="false"/>
        </tx:attributes>
    </tx:advice>

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Base Dao Definitions
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="baseExpressDAO" class="sg.com.diamond.express.base.dao.impl.BaseHibernateDaoImpl" abstract="true">
        <property name="sessionFactory" ref="expressSessionFactory"/>
    </bean>

真的
真的
10
org.hibernate.dialen.oracle10galent
问题

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Data Source Configuration
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="targetDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@192.168.170.36:1521:EXPT2" />
        <property name="username" value="EXP_USER" />
        <property name="password" value="passw0rd" />
    </bean>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <property name="targetDataSource" ref="targetDataSource"/>
    </bean>

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Hibernate abstract session factory parent
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="baseSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" abstract="true">
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
            </props>
        </property>
    </bean>

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Hibernate entity configurations
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="expressSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" parent="baseSessionFactory">
        <property name="hibernateProperties">
            <props merge="true">
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
            </props>
        </property>
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingLocations" value="classpath*:hbm/express/*.hbm.xml"/>
    </bean>

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Transaction Management
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="expressSessionFactory"/>
    </bean>

    <aop:config>
        <aop:pointcut id="servicePointcut" expression="execution(* sg.com.diamond.express.webadmin.service.*.*.*(..))"/>
        <aop:advisor id="serviceTx" advice-ref="txAdvice" pointcut-ref="servicePointcut"/>
    </aop:config>

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*"      propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="true" />
            <tx:method name="search*"   propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="true" />
            <tx:method name="list*"     propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="true" />
            <tx:method name="is*"       propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="true" />
            <tx:method name="*"         propagation="REQUIRES_NEW" isolation="READ_COMMITTED" read-only="false"/>
        </tx:attributes>
    </tx:advice>

    <!--|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        | Base Dao Definitions
        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  -->
    <bean id="baseExpressDAO" class="sg.com.diamond.express.base.dao.impl.BaseHibernateDaoImpl" abstract="true">
        <property name="sessionFactory" ref="expressSessionFactory"/>
    </bean>
为什么会发生错误?而且它不会破坏我的应用程序,日志级别是调试,而不是错误,我的应用程序可以在这之后正常继续

我的配置正确吗

注意

不要介意完整的xml配置,出于某种原因,我需要使用完整的xml和无注释

回答

在研究了aop切入点表达式之后,我注意到在我编写的一个简单批处理程序中,我只有1个上下文,没有这个问题

这让我找到了答案

我最初将SpringXML配置结构化为多个层

  • 在顶层,在应用程序上下文中,我声明了所有数据源和事务管理
  • 在第二层,servlet层,每个servlet都有自己的上下文
  • 这个“第二级”上下文应该有多个,例如,一个servlet上下文应该处理所有RESTful服务,而另一个上下文处理web ui
我假设它将在应用程序上下文中进行事务管理设置来构建它。有点像“所有servlet上下文都应该能够以相同的方式使用相同的数据源和事务管理”

但事实证明,事实并非如此

当我将事务管理部分(包括数据源配置)移动到servlet上下文配置中时,一切正常,服务现在正确地包装在事务下


谢谢。

发生此错误是因为您的aop事务配置不正确。它不包括堆栈跟踪中的服务类。请调整映射,直到停止获取堆栈跟踪。或者,如果可能,最好使用带注释的事务配置。 第二个问题的答案在hibernate模板的源代码中:

try {
325         session =     getSessionFactory().getCurrentSession();
326         }
327         catch (HibernateException ex) {
328             logger.debug("Could not retrieve pre-bound Hibernate session", ex);
329         }
330         if (session == null) {
331             session = getSessionFactory().openSession();
332             session.setFlushMode(FlushMode.MANUAL);
333             isNew = true;
334         }

基于“sg.com.diamond.webadmin.service.impl.ClientProfileService”的类名和searchByName(字符串名)的方法名,您建议我使用什么样的切入点表达式?您已经为我指出了正确的答案。我将更新问题以反映我找到的答案,并将此答案标记为正确。
try {
325         session =     getSessionFactory().getCurrentSession();
326         }
327         catch (HibernateException ex) {
328             logger.debug("Could not retrieve pre-bound Hibernate session", ex);
329         }
330         if (session == null) {
331             session = getSessionFactory().openSession();
332             session.setFlushMode(FlushMode.MANUAL);
333             isNew = true;
334         }