【问题标题】:"No Session found for current thread" when adding @Autowire添加@Autowire 时“找不到当前线程的会话”
【发布时间】:2012-08-28 18:35:43
【问题描述】:

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

总结:当我在 .xml 上创建和注入 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: No Session found for current thread 被提出:

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,也会发生同样的情况。

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

【问题讨论】:

    标签: spring hibernate


    【解决方案1】:

    问题很可能是在 dispatcher-servlet.xml 配置中提取了 @Repository@Service 注释(你使用 context:component-scan 吗?),所以这些 bean 是在 dispatcher servlet 上下文中创建的,而不是根网络应用上下文。

    一个好的做法是将您的服务层对象放到专用包中,并使用特定包名称作为&lt;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

    【讨论】:

    • 这就是解决方案。 CopyPasteException 在我这边。
    猜你喜欢
    • 2019-08-03
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2015-05-28
    • 2014-09-29
    相关资源
    最近更新 更多