18

我正在尝试使用 Spring 3.1 和 Hibernate 4 设置我的项目。我一直在关注一些在线教程。我收到一个奇怪的错误,根据 spring 论坛应该已经用 Spring 3.1 修复了。 春季错误追踪器

当我的服务调用getCurrentSession()时,它会引发以下异常:

org.hibernate.HibernateException: **No Session found for current thread**] with root cause org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) at
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:881)

****编辑:根据 Spring Spring 3.1 Documentation for Transactions更新了我的 spring-dao.xml 。我尝试用 org.apache.commons.dbcp.BasicDataSource 替换我的数据源。我的配置中是否缺少任何可能导致此问题的属性?****

这是我的 spring-dao.xml:

 <!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />   

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="hibernateProperties">
        <value>hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect</value>
    </property>
</bean>

<!-- Declare a datasource that has pooling capabilities-->   
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
            destroy-method="close"
            p:driverClass="${app.jdbc.driverClassName}"
            p:jdbcUrl="${app.jdbc.url}"
            p:user="${app.jdbc.username}"
            p:password="${app.jdbc.password}"
            p:acquireIncrement="5"
            p:idleConnectionTestPeriod="60"
            p:maxPoolSize="100"
            p:maxStatements="50"
            p:minPoolSize="10" />

<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" 
            p:sessionFactory-ref="sessionFactory" />

我的用户 bean (User.java)

package com.foo.lystra.beans;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="users")
public class User implements Serializable {
private static final long serialVersionUID = -5527566191402296042L;

@Id
@Column(name = "idusers")
private Integer user_id;

@Column(name="login_name")
private String loginName;

@Column(name="password")
private String password;

@Column(name="role")
private String role;

@Column(name="congregation_id")
private Integer congregation_id;

public Integer getUser_id() {
    return user_id;
}
public void setUser_id(Integer user_id) {
    this.user_id = user_id;
}
public String getLoginName() {
    return loginName;
}
public void setLoginName(String loginName) {
    this.loginName = loginName;
}
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}
public String getRole() {
    return role;
}
public void setRole(String role) {
    this.role = role;
}
public Integer getCongregation_id() {
    return congregation_id;
}
public void setCongregation_id(Integer congregation_id) {
    this.congregation_id = congregation_id;
}

public String toString() {
    return "user_name: " + this.loginName + " congregation_id: " + this.congregation_id.toString();
}
}

最后我的服务...

package com.foo.lystra.services;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.foo.lystra.beans.User;
import com.foo.lystra.beans.Congregation;

@Service("congregationUserService")
@Transactional
public class CongregationUserService {
protected static Log logger = LogFactory.getLog(CongregationUserService.class);

@Resource(name="sessionFactory")
private SessionFactory sessionFactory;

public List<User> getAllUsers() {
    logger.debug("getting all users");

            //Exception is thrown on this next line:
    Session session = sessionFactory.getCurrentSession();

    Query query = session.createQuery("FROM users");
    return query.list();
}
}

我意识到我的数据源可能没有被使用。如果我忘记包含任何配置,我可以更新这篇文章。此外,如果需要 Tomcat 启动日志,我也可以提供它们。

4

14 回答 14

12

我在 Web 应用程序中遇到了同样的问题。问题在于两个配置文件中都存在哪个:application-context.xml 和 webmvc-context.xml。webmvc-context.xml 在 application-context.xml 之后加载。我认为在加载 application-context.xml 时首先使用事务引用加载 DAO 类,但是在加载 webmvc-context.xml 时,它会替换为另一个对象,没有事务引用。无论如何,我解决了扫描特定包的问题:
<context:component-scan base-package="com.app.repository" />
application-context.xml 和
<context:component-scan base-package="com.app.web" />
webmvc-context.xml。

于 2012-10-08T14:21:14.157 回答
6

我在 spring-4.0.6 和 hibernate-4.3.6 上遇到了这个问题。

解决方案是将所有注释驱动、组件扫描、注释驱动的指令从 root-context.xml 移动到 servlet-context.xml:

<mvc:annotation-driven />
<context:component-scan base-package="ru.dd.demo" />
<tx:annotation-driven transaction-manager="transactionManager" />

dataSource、sessionFactory 和 transactionManager 仍然可以在 root-context.xml 中定义。

于 2014-08-01T02:38:04.730 回答
2

它是一个网络应用程序吗?如果是这样考虑使用 OpenSessionInViewFilter。因为我相信在使用 currentSession (绑定到当前线程)时,代码中必须有一个点将会话与线程解除绑定。

我不确定事务管理器是否这样做。

于 2012-01-21T22:38:20.297 回答
2

我和你有同样的错误。

这是一个尚未解决的错误。

https://jira.springsource.org/browse/SPR-9028

尝试将休眠 jar 文件更改为 3.6。因为 Spring 使用它。

http://mvnrepository.com/artifact/org.springframework/spring-orm/3.1.0.RELEASE

这里 Spring 3.1 工件和依赖项

于 2012-03-01T13:55:49.880 回答
1

Spring Reference (3.2.x) 中所述:

在 Web MVC 框架中,每个 DispatcherServlet 都有自己的 WebApplicationContext,它继承了根 WebApplicationContext 中已经定义的所有 bean。这些继承的 bean 可以在特定于 servlet 的范围内被覆盖,并且您可以在给定的 Servlet 实例本地定义新的特定于范围的 bean。

因此,定义或扫描的 Bean<context:component-scan>将在您的控制器中可见,因此您可以 @Autowired 它们,但在其他 applicationContext* 文件中不可见,因此除非<tx:annotation-driven/>在 DispatcherServlet 的配置中未定义,否则@Transactional将不起作用。

所以我猜<context:component-scan>你的 DispatcherServlet 的配置和<tx:annotation-driven/>声明中可能有一个 applicationContext*.xml,所以@Autowired工作正常,但@Transactional不是。

于 2013-03-11T13:51:33.630 回答
1

我遇到了同样的问题并测试了所有已回答的解决方案。Vali 的回答很有帮助。对我有用的是将这些 bean 从 applicationContext.xml 移动到 web-servlet.xml:

<bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>       
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

此外,您需要添加 web-servlet.xml:

xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"

xsi:schemaLocation="       
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    "
于 2013-06-16T13:38:39.327 回答
1

在 web.xml 中添加 OpenSessionInViewFilter 过滤器

<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name>
        <param-value>sessionFactory</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>
于 2013-07-08T14:29:02.093 回答
0

不确定,但问题可能出在p:packagesToScan. 您的 ConfigurationUserService 在包中,com.foo.lystra.servicesp:packagesToScancom.foo.lystra.beans

于 2012-01-13T06:31:41.180 回答
0

您的配置不指向带注释的类。添加它们

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
  <property name="hibernateProperties">
     <value>hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect</value>
  </property>

  <property name="annotatedClasses">
    <list>
      <value>test.package.Foo</value>
      <value>test.package.Bar</value>
    </list>
  </property>
</bean>

它类似于之前的AnnotationSessionFactoryBean在此处检查 Api 。

于 2012-01-18T09:38:36.310 回答
0

我相信你需要:

<context:component-scan base-package="com.foo.package" />

否则 spring 上下文将找不到您的服务,因此不会使用事务方面包装您的方法。

于 2012-01-25T00:24:25.947 回答
0

有完全相同的错误,只需为我的服务创建一个接口即可解决。所以在你的情况下,我会创建:

public interface ICongregationUserService {
   public List<User> getAllUsers();
}

然后更改 CongregationUserService 来实现它:

@Service("congregationUserService")
@Transactional
public class CongregationUserService implements ICongregationUserService{
   //...
}

在您自动连接 CongregationUserService 的地方,改为自动连接 ICongregationUserService:

@Autowired
private ICongregationUserService congregationUserService;
于 2013-03-15T19:39:00.353 回答
0

我通过放入<tx:annotation-driven transaction-manager="miTransactionManager"/>dispatcher-servlet.xml 而不是任何其他 xml 配置文件解决了这个问题。

我认为这种方式可以让 bean 在同一个 spring 上下文中共存。

于 2013-07-02T07:59:55.320 回答
0

我发现这个问题是春天的一个错误

此链接https://jira.springsource.org/browse/SPR-9020报告了问题..

为了修复它,我使用了 Matias Mirabelli 的解决方法,可以在此链接https://gist.github.com/seykron/4770724上找到

发生的事情是带有注释的方法Propagation.SUPPORTS支持事务,但是如果没有事务绑定到线程,那么spring而不是创建一个新会话,它会抛出一个HibernateException

为了配置解决方案,您可以使用 hibernate 属性:

hibernate.current_session_context_class = com.your.package.TransactionAwareSessionContext

于 2013-12-12T17:11:30.763 回答
0

我放

<context:component-scan base-package="com.sprhib.repo"/>  #(some class files are annotaed by @Repository,@Service,@Component)
<tx:annotation-driven transaction-manager="txManager" />
<task:annotation-driven/>

int root.xml。

我把

<context:component-scan base-package="com.sprhib.web"/>  #(some class files are annotaed by @Controller)
<mvc:annotation-driven />

int servlet-context.xml。

有用。

于 2016-05-06T13:51:59.200 回答