spring - 添加@Autowire时为"No Session found for current thread"

标签 spring hibernate

我见过几个类似的问题,但建议的解决方案都没有帮助我。

摘要:当我在 .xml 上创建并注入(inject) bean 时,它可以工作;但当我使用 @Autowire 或 @Resource 时,它​​不会。

环境:Spring3、Hibernate4、Tomcat7。

详细信息:以下设置确实有效:

web.xml:

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      /WEB-INF/spring/root-context.xml
      /WEB-INF/spring/security-context.xml
      /WEB-INF/spring/users-context.xml
    </param-value>
  </context-param>

root-context.xml:

  <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/venus" />
    <property name="username" value="root" />
    <property name="password" value="" />
  </bean>

  <bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.airbus.genesis.marte.dal" />
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.show_sql">true</prop>
      </props>
    </property>
  </bean>

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

users-context.xml:

  <bean id="usersDAO" class="com.airbus.genesis.marte.dal.users.UsersDAO">
    <property name="sessionFactory" ref="sessionFactory" />
  </bean>

BL 对象:

@Service("usersManager")
@Transactional(readOnly = true)
public class UsersManager implements IUsersManager {
  @Autowired
  @Qualifier("usersDAO")
  private IUsersDAO usersDAO;

  @Override
  public List<User> getUsers() {
    return usersDAO.getUsers();
  }

}

DAO 对象(注意 @Repository 和 @Resource 被注释):

//@Repository("usersDAO")
@Transactional(readOnly = true)
public class UsersDAO implements IUsersDAO {

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

  @Override
  public List<User> getUsers() {
    @SuppressWarnings("unchecked")
    List<User> res = (List<User>) getSessionFactory().getCurrentSession()
        .createQuery("from User").list();
    return res;
  }

  public SessionFactory getSessionFactory() {
    return sessionFactory;
  }

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

但是以下一个不起作用:

users-context.xml:

<!-- 
  <bean id="usersDAO" class="com.airbus.genesis.marte.dal.users.UsersDAO">
    <property name="sessionFactory" ref="sessionFactory" />
  </bean>
-->

DAO 对象(请注意,@Repository 和 @Resource 现在已取消注释):

@Repository("usersDAO")
@Transactional(readOnly = true)
public class UsersDAO implements IUsersDAO {

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

  @Override
  public List<User> getUsers() {
    @SuppressWarnings("unchecked")
    List<User> res = (List<User>) getSessionFactory().getCurrentSession()
        .createQuery("from User").list();
    return res;
  }

  public SessionFactory getSessionFactory() {
    return sessionFactory;
  }

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

org.hibernate.HibernateException:未找到当前线程的 session 引发:

org.hibernate.HibernateException: No Session found for current thread
    org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
    org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:941)
    com.airbus.genesis.marte.dal.users.UsersDAO.getUsers(UsersDAO.java:23)
    com.airbus.genesis.marte.bl.users.UsersManager.getUsers(UsersManager.java:22)
[...]

如果我使用 @Autowire 而不是 @Resource,也会发生同样的情况。

我想这是我这边的某种误解,但找不到哪里。有什么想法吗?

最佳答案

问题可能是 @Repository@Service注释是在dispatcher-servlet.xml 配置中选取的(您使用context:component-scan 吗?),因此这些bean 是在dispatcher servlet 上下文而不是根Web 应用程序上下文中创建的。

一个好的做法是将服务层对象放入专用包中,并使用特定的包名称 <context:component-scan/> base-package限定符(如“com.myproject.services”)。您还可以使用过滤表达式来包含和排除元素,请参阅此处的示例:@Service are constructed twiceSpring documentation 的 4.10.3 部分

另请参阅Difference between applicationContext.xml and spring-servlet.xml in Spring Framework

关于spring - 添加@Autowire时为"No Session found for current thread",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12257752/

相关文章:

java - 运行 Java Web 应用程序的最低要求

java - Hibernate 处理日期和时间 - PostgreSql

java - Hibernate EntityManager 包含 Core 吗?

java - 使用 HQL 删除对象之间的关系

java - Hibernate setParemeter 是从 1 开始还是从 0 开始?查询参数异常

java - spring mvc拦截器如何获取方法执行流程

java - Http 出站网关从 pojo 负载发送 Json 请求

java - 即使启用全部级联后,也无法从具有子记录的父表中删除记录

java - 有没有办法在 Spring XML 中指定默认属性值?

java - 如何使用 Tomcat 上下文使用 Java 控制台应用程序和 Hibernate?