2

同様の質問をいくつか見ましたが、提案された解決策はどれも役に立ちませんでした。

概要: .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)
[...]

@Resource の代わりに @Autowire を使用すると、同じことが起こります。

私の側の何らかの誤解だと思いますが、どこを見つけることができません。何か案が?

4

1 に答える 1

2

問題は、dispatcher-servlet.xml 構成で注釈が取得されている可能性が高いため (使用します@Repositoryか?)、これらの Bean は、ルート Web アプリ コンテキストではなく、ディスパッチャー サーブレット コンテキストで作成されます。@Servicecontext:component-scan

サービス レイヤー オブジェクトを専用パッケージに配置し、特定のパッケージ名を<context:component-scan/>base-package修飾子 (「com.myproject.services」など) として使用することをお勧めします。フィルター式を使用して要素を含めたり除外したりすることもできます。ここで例を参照してください: @Service は 2 回構築され、 Spring ドキュメント の 4.10.3 セクション

Spring Framework の applicationContext.xml と spring-servlet.xml の違いも参照してください。

于 2012-09-04T07:18:13.180 に答える