我有這個基本上查詢數據庫並返回所有持久實體的Web服務。爲了測試的目的,我創建了一個TestDataManager,它在加載Spring上下文後保留2個示例實體(順便說一下,我正在使用JAX-WS,Spring,Hibernate和HSQLDB)。爲什麼我不能檢索我剛纔堅持的實體?
我TestDataManager看起來是這樣的:
@Component
public class TestDataManager {
@Resource
private SessionFactory sf;
@PostConstruct
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void insertTestData(){
sf.openSession();
sf.openSession().beginTransaction();
sf.openSession().persist(new Site("site one"));
sf.openSession().persist(new Site("site two"));
sf.openSession().flush();
}
}
我的JAX-WS端點看起來是這樣的:
@WebService
public class SmartBrickEndpoint {
@Resource
private WebServiceContext context;
public Set<Site> getSitesForUser(String user){
return getSiteService().findByUser(new User(user));
}
private ISiteService getSiteService(){
ServletContext servletContext = (ServletContext) context.getMessageContext().get("javax.xml.ws.servlet.context");
return (ISiteService) BeanRetriever.getBean(servletContext, ISiteService.class);
}
}
這是我的服務類:
@Component
@Transactional(readOnly = true)
public class SiteService implements ISiteService {
@Resource
private ISiteDao siteDao;
@Override
public Set<Site> findByUser(User user) {
return siteDao.findByUser(user);
}
}
這是我的DAO:
@Component
@Transactional(readOnly = true)
public class SiteDao implements ISiteDao {
@Resource
private SessionFactory sessionFactory;
@Override
public Set<Site> findByUser(User user) {
Set<Site> sites = new LinkedHashSet<Site>(sessionFactory.getCurrentSession().createCriteria(Site.class).list());
return sites;
}
}
這是我的applicationContext.xml:
<context:annotation-config />
<context:component-scan base-package="br.unirio.wsimxp.dao"/>
<context:component-scan base-package="br.unirio.wsimxp.service"/>
<context:component-scan base-package="br.unirio.wsimxp.spring"/>
<bean id="applicationDS" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:file:sites"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="applicationDS" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.connection.release_mode">on_close</prop>
<!--<prop key="hibernate.current_session_context_class">thread</prop>-->
<prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
這就是現在事情:
- 當應用程序部署,TestDataManager#insertTestData踢入(因@PostConstruct)和堅持不會引發任何異常。到目前爲止,我應該在數據庫中擁有2個實體。
- 之後,我通過SOAP客戶端調用端點,並且請求一直到達到DAO。 Hibernate調用不會引發任何異常,但返回的列表是空的。
奇怪的是,在TestDataManager,如果切換從sf.openSession()
到sf.getCurrentSession()
,我得到一個錯誤信息:「沒有Hibernate的Session綁定到線程,配置不允許非事務之一創建這裏」。
我在做什麼錯在這裏?爲什麼查詢「沒有看到」持久實體?爲什麼我需要在TestDataManager上調用sf.openSession()
,儘管它的註釋是@Transactional
?
我已經在application.xml中用hibernate.current_session_context_class=thread
做了一些測試,但是我只是在每個類中切換問題。我想不需要手動調用sf.openSession()
並讓Hibernate保持小心。
非常感謝您的幫助!
你有沒有解決問題了嗎?您是否嘗試過下面的解決方案? –