Java - Spring、Hibernate:没有会话绑定到线程

发布于 2024-12-11 10:15:59 字数 11124 浏览 0 评论 0 原文

我尝试使用 Spring、Rest、Hibernate 创建一个小示例。为了在编组完成时打开会话,我在 web.xml 中添加了过滤器 org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

但是现在,我陷入了困境,这可能是因为我AOP 相当新。当发送请求时,我面临会话未打开的问题:

20.10.2011 17:26:40 org.apache.catalina.core.StandardWrapperValve invoke
SCHWERWIEGEND: Servlet.service() for servlet mvc-dispatcher threw exception
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:685)

我认为这与 带有注释的 Spring + Hibernate:没有 Hibernate 会话绑定到线程 但我无法让它工作。

web.xml:

<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Spring Web MVC Application</display-name>

<filter>
    <filter-name>SessionPerRequest</filter-name>
    <filter-class>
        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>SessionPerRequest</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>

mvc-dispatcher-servlet.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-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="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/test" />
    <property name="username" value="backend"/>
    <property name="password" value="bUWGRysbbzYuXsbq" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<context:component-scan base-package="de.company.springtest" />

<mvc:annotation-driven />

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configurationClass">
        <value>org.hibernate.cfg.AnnotationConfiguration</value>
    </property>
</bean>


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

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<!--    <aop:config> -->
<!--        <aop:advisor pointcut="execution(* de.company.springtest..*.*(..))" advice-ref="txAdvice" /> -->
<!--    </aop:config> -->


</beans>

如果aop部分未注释(这是另一个线程中的解决方案),则在启动时会抛出以下异常:

    INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@46e06703: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,dataSource,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,JSONController,hibernateConfiguration,org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,sessionFactory,transactionManager,txAdvice,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0,sessionFactoryBean]; root of factory hierarchy
20.10.2011 17:37:04 org.springframework.web.context.ContextLoader initWebApplicationContext
SCHWERWIEGEND: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot resolve reference to bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0' while setting bean property 'transactionAttributeSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:452)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)

Rest控制器,但是尚未调用它。因此函数开头的断点不会被调用。

package de.company.springtest.controller;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import de.company.springtest.Item;
import de.company.springtest.Order;


@Controller
@RequestMapping("/user")
// localhost:8080/RESTfulTest/rest/user/abc
public class JSONController {

@Autowired
private SessionFactory sessionFactory;

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody
Order postOrderInJSON() {

    Session session = sessionFactory.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Order order = new Order();
    order.getItems().add(new Item());
    session.save(order);
    // session.flush();
    transaction.commit();
    // session.close();
    return order;

}


@RequestMapping(value = "get/{id}", method = RequestMethod.GET)
public @ResponseBody
Order getUserInJSON(/* @PathVariable Long id */) {

    Session session = sessionFactory.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Order order = new Order();
    order.getItems().add(new Item());
    session.save(order);
    // session.flush();
    transaction.commit();
    // session.close();

    return order;

}

}

HibernateConfiguration.java

package de.company.springtest;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.dialect.MySQLDialect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

@Configuration
public class HibernateConfiguration {

@Value("#{dataSource}")
private DataSource dataSource;

@Bean
public AnnotationSessionFactoryBean sessionFactoryBean() {
    Properties props = new Properties();
    props.put("hibernate.dialect", MySQLDialect.class.getName());
    props.put("hibernate.current_session_context_class", "thread");
    props.put("hibernate.transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory");
    props.put("hibernate.format_sql", "true");

    AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();
    bean.setAnnotatedClasses(new Class[]{Item.class, Order.class});     
    bean.setHibernateProperties(props);
    bean.setDataSource(this.dataSource);
    bean.setSchemaUpdate(true);
    return bean;
}

@Bean
public HibernateTransactionManager transactionManager() {
    HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager( sessionFactoryBean().getObject() );
    return hibernateTransactionManager;
}

}

您有什么建议可以让我继续搜索吗?

I tried creating a small example using Spring, rest, Hibernate. In order to have the session open for when the marshalling is done, I added the filter org.springframework.orm.hibernate3.support.OpenSessionInViewFilter in the web.xml

Now, however, I get heavily stuck, which might be because I'm pretty new with AOP. I face the problem that the session is not opened, when a request is sent:

20.10.2011 17:26:40 org.apache.catalina.core.StandardWrapperValve invoke
SCHWERWIEGEND: Servlet.service() for servlet mvc-dispatcher threw exception
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:685)

I think it is the same problem as described in Spring + Hibernate with annotations: No Hibernate Session bound to thread but I don't get it to work.

web.xml:

<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Spring Web MVC Application</display-name>

<filter>
    <filter-name>SessionPerRequest</filter-name>
    <filter-class>
        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>SessionPerRequest</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>

mvc-dispatcher-servlet.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-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="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/test" />
    <property name="username" value="backend"/>
    <property name="password" value="bUWGRysbbzYuXsbq" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<context:component-scan base-package="de.company.springtest" />

<mvc:annotation-driven />

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configurationClass">
        <value>org.hibernate.cfg.AnnotationConfiguration</value>
    </property>
</bean>


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

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<!--    <aop:config> -->
<!--        <aop:advisor pointcut="execution(* de.company.springtest..*.*(..))" advice-ref="txAdvice" /> -->
<!--    </aop:config> -->


</beans>

If the aop part is uncommented (which is the solution in the other thread), it throws the following exception when it is starting:

    INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@46e06703: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,dataSource,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,JSONController,hibernateConfiguration,org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,sessionFactory,transactionManager,txAdvice,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0,sessionFactoryBean]; root of factory hierarchy
20.10.2011 17:37:04 org.springframework.web.context.ContextLoader initWebApplicationContext
SCHWERWIEGEND: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot resolve reference to bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0' while setting bean property 'transactionAttributeSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:452)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)

Rest controller, which however does not yet get called. So break points in the very beginning of the functions are not called.

package de.company.springtest.controller;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import de.company.springtest.Item;
import de.company.springtest.Order;


@Controller
@RequestMapping("/user")
// localhost:8080/RESTfulTest/rest/user/abc
public class JSONController {

@Autowired
private SessionFactory sessionFactory;

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody
Order postOrderInJSON() {

    Session session = sessionFactory.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Order order = new Order();
    order.getItems().add(new Item());
    session.save(order);
    // session.flush();
    transaction.commit();
    // session.close();
    return order;

}


@RequestMapping(value = "get/{id}", method = RequestMethod.GET)
public @ResponseBody
Order getUserInJSON(/* @PathVariable Long id */) {

    Session session = sessionFactory.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Order order = new Order();
    order.getItems().add(new Item());
    session.save(order);
    // session.flush();
    transaction.commit();
    // session.close();

    return order;

}

}

HibernateConfiguration.java

package de.company.springtest;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.dialect.MySQLDialect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

@Configuration
public class HibernateConfiguration {

@Value("#{dataSource}")
private DataSource dataSource;

@Bean
public AnnotationSessionFactoryBean sessionFactoryBean() {
    Properties props = new Properties();
    props.put("hibernate.dialect", MySQLDialect.class.getName());
    props.put("hibernate.current_session_context_class", "thread");
    props.put("hibernate.transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory");
    props.put("hibernate.format_sql", "true");

    AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();
    bean.setAnnotatedClasses(new Class[]{Item.class, Order.class});     
    bean.setHibernateProperties(props);
    bean.setDataSource(this.dataSource);
    bean.setSchemaUpdate(true);
    return bean;
}

@Bean
public HibernateTransactionManager transactionManager() {
    HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager( sessionFactoryBean().getObject() );
    return hibernateTransactionManager;
}

}

Do you have any proposition where I could continue with my search?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

も让我眼熟你 2024-12-18 10:15:59

取消注释该部分时的错误很可能是由于类路径中缺少aspectj引起的。

或者,您可以在 DAO 中或任何适合您的应用程序设计的开始/结束事务中使用 @Transactional 注释,正如链接线程中的第一个注释所指出的那样。您需要其中任何一个来启动事务(或手动执行) - 仅配置事务管理器是不够的。

The error when uncommenting the part is most likely caused by aspectj missing in the classpath.

Alternatively, you could use the @Transactional annotation in your DAO or wherever beginning/ending transactions fits in your application design, as the first comment in the linked thread points out. You need to have either of this to start a transaction (or do it manually) - just having a transaction manager configured isn't enough.

转角预定愛 2024-12-18 10:15:59

嵌套异常是 java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException

您需要将aspectJ (aspectjweaver.jar) 与您的应用程序一起部署。

如果您使用 Maven,则将其添加到您的 pom 中:

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.9</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.6.9</version>
    </dependency>

如果您不使用 Maven,则手动添加这两个罐子。

nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException

You need to deploy aspectJ (aspectjweaver.jar) together with your application.

If you use maven than add this to your pom:

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.9</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.6.9</version>
    </dependency>

If you do not use maven, than add this two jars by hand.

娇柔作态 2024-12-18 10:15:59

你的整个配置/接线看起来很“原始”。出现此异常的原因=>你的“服务层”没有被处理,因此 Hibernate 会抱怨。

不要将 @Transactional 放在 DAO 级别,正如有人建议的 =>这是错误的。您应该始终在业务单位上进行交易 =>在服务层。

看一下集成 Spring 和 Hibernate 的示例项目(只需克隆它)一起。

实际上有一个 HibernateSessionNotBoundToThreadIntegrationTest 显示此异常的原因。

这是 示例

<?xml version="1.0" encoding="UTF-8"?>
<beans ...>

    <aop:config>
        <aop:pointcut id="moneyMakingBusinessServiceMethods"
                      expression="execution(* org.gitpod.startup.service.MoneyMakingBusinessService.*(..))"/>

        <aop:advisor advice-ref="moneyMakingAdvice"
                     pointcut-ref="moneyMakingBusinessServiceMethods"/>
    </aop:config>

    <tx:advice id="moneyMakingAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="makeMoney" propagation="REQUIRED"/>
            <tx:method name="withdrawMoney" propagation="REQUIRED" read-only="true"/>            
            <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>

</beans>

You whole configuration / wiring looks pretty "raw". The reason for this exception => your "service layer" is not transacted, hence Hibernate complains.

Do not put @Transactional at the DAO level, as somebody suggests => it is wrong. You should always transact on the business unit => in the service layer.

Take a look at the example project (just clone it) that integrates Spring and Hibernate together.

There is actually a HibernateSessionNotBoundToThreadIntegrationTest that shows the reason for this exception.

Here is an example on the proper TX configuration via Spring AOP:

<?xml version="1.0" encoding="UTF-8"?>
<beans ...>

    <aop:config>
        <aop:pointcut id="moneyMakingBusinessServiceMethods"
                      expression="execution(* org.gitpod.startup.service.MoneyMakingBusinessService.*(..))"/>

        <aop:advisor advice-ref="moneyMakingAdvice"
                     pointcut-ref="moneyMakingBusinessServiceMethods"/>
    </aop:config>

    <tx:advice id="moneyMakingAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="makeMoney" propagation="REQUIRED"/>
            <tx:method name="withdrawMoney" propagation="REQUIRED" read-only="true"/>            
            <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>

</beans>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文