我见过几个类似的问题,但没有一个建议的解决方案对我有帮助。
总结:当我在.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,也会发生同样的情况。
我想这是我身边的某种误解,但找不到哪里。有什么想法吗?
答案 0 :(得分:2)
问题很可能是在dispatcher-servlet.xml配置中拾取@Repository
和@Service
注释(你使用context:component-scan
吗?),所以这些bean是在调度程序servlet上下文而不是根Web应用程序上下文。
一个好的做法是将服务层对象放到专用包中,并使用特定的包名称<context:component-scan
/&gt; base-package
限定符(如'com.myproject.services')。您还可以使用过滤器表达式来包含和排除元素,请参阅此处的示例:@Service are constructed twice
和Spring documentation
另见Difference between applicationContext.xml and spring-servlet.xml in Spring Framework