次のエラーを取得しています
org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.Java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.Java:1024)
at com.fexco.shoptaxfreemobile.service.ProfileService.registerVisitor(ProfileService.Java:57)
at com.fexco.shoptaxfreemobile.controller.ProfileController.registerVisitor(ProfileController.Java:91)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.Java:213)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:126)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.Java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:668)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:770)
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:305)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:210)
at com.fexco.shoptaxfreemobile.jsonp.JsonpCallbackFilter.doFilter(JsonpCallbackFilter.Java:33)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.Java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.Java:259)
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:243)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:210)
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:224)
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:169)
at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:472)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:168)
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:98)
at org.Apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.Java:928)
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:118)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:407)
at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:987)
at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:539)
at org.Apache.Tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.Java:300)
at Java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.Java:886)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:908)
at Java.lang.Thread.run(Thread.Java:619)
サービスクラス
@Service
public class ProfileService {
@Resource(name = "mySessionFactory")
private SessionFactory sessionFactory;
@Autowired
private ProfileDao profileDao;
private class CountrySorter implements Comparator<Country> {
@Override
public int compare(Country country1, Country country2) {
if ( country1.getId().compareTo(new Long (3)) < 0){
return country1.getId().compareTo(country2.getId());
}
return country1.getName().compareToIgnoreCase(country2.getName());
}
}
public List<Country> getCountries() {
List<VisitorCountry> visitorCountries = profileDao.getAllCountries();
List<Country> countries = new ArrayList<Country>();
for ( VisitorCountry country : visitorCountries){
countries.add(country.getCountry());
}
Comparator<Country> comparator = new CountrySorter();
Collections.sort(countries, comparator);
return countries;
}
public RegisterResponse registerVisitor(JsonVisitor visitorDetails){
Visitor storedVisitor = (Visitor) sessionFactory.getCurrentSession().get(Visitor.class, visitorDetails.getTfscNumber(), LockMode.NONE);
if ( storedVisitor == null){
storedVisitor = new Visitor(visitorDetails);
}else{
storedVisitor.setVisitorDetails(visitorDetails);
}
try{
sessionFactory.getCurrentSession().saveOrUpdate(storedVisitor);
}catch(Exception ex){
return new RegisterResponse(false, "Failed To Register Card. Please Try Again Later.", visitorDetails);
}
return new RegisterResponse(true, "", visitorDetails);
}
}
dAOクラスのビット
@Service
@Transactional
public class ProfileDao {
@Resource(name = "mySessionFactory")
private SessionFactory sessionFactory;
public List getAllCountries(){
List<VisitorCountry> visitorCountries = sessionFactory.getCurrentSession()
.getNamedQuery("GET_ALL_COUNTRIES").list();
return visitorCountries;
}
public List<Retailer> getRetailerByRetailerNumber(String retailerNo) {
List<Retailer> retailerByRetailerNumber = sessionFactory.getCurrentSession()
.getNamedQuery("FindRetailerByRetailerNo").setString("retailerNo", retailerNo).list();
return retailerByRetailerNumber;
}
そして、私はapplication-context.xmlにこれを持っています
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<value>
<![CDATA[
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
]]>
</value>
</property>
</bean>
誰も私が次のエラーを受け取っている理由を見つけることができますか?
Daoクラスに@Transactionalで注釈を付けましたが、サービスクラスには注釈を付けていません。この線:
Visitor storedVisitor =
(Visitor) sessionFactory.getCurrentSession().get(Visitor.class,
visitorDetails.getTfscNumber(), LockMode.NONE);
トランザクションに参加する必要があります。
これを修正するには、@ TransactionalアノテーションをProfileServiceクラスに追加するか、registerVisitor()メソッドのみを追加します。
私は次の2つのステップで同じ問題を解決しました
このページの回答で、提案されたjordan002としてサービスメソッドに@Transactional
を配置しました。
もう1つ、2つの構成ファイルがある場合:application-context.xml
(DBおよびアプリケーションコンテキスト固有の構成用)およびwebmvc-context.xml
(Web /コントローラー固有の構成用)と言う場合は、使用しているパッケージごとに異なるパッケージをスキャンする必要がありますコントローラーとdao。
webmvc-context.xml
はapplication-context.xml
の後にロードされます。 DAOクラスは、application-context.xmlがロードされるときに最初にトランザクション参照でロードされますが、webmvc-context.xmlがロードされると、トランザクション参照なしで別のオブジェクトに置き換えられます。
いずれにせよ、スキャンした特定のパッケージの問題を解決します。
<context:component-scan base-package="com.app.repository" />
application-context.xml
そして
<context:component-scan base-package="com.app.web" />
webmvc-context.xml
の場合。
@Repositoryを使用してDAOの注釈を変更する
@Repository
public class ProfileDao {
.
.
.
}
そして、あなたのサービスメソッドを@Transactionalにします
@Transactional
public List<Retailer> getRetailerByRetailerNumber(String retailerNo) {}
上記の問題を2つのステップで解決しました
1-DAOメソッドを呼び出すサービスメソッドに@Transactionalサポートを追加する
2-この方法でspring-servlet.xmlにapplicationContext.xmlをインポートする
<import resource="applicationContext.xml" />
<mvc:annotation-driven />
<context:component-scan base-package="com.json.api.*" />
<!--Third Party Integration should be injected in xml start here -->
<bean id="integrationInterface" class="com.json.api.IntegerationInterface"></bean>
<!--Third Party Integration should be injected in xml start here -->
<mvc:interceptors>
<bean id="apiServiceInterceptor" class="com.json.api.interceptor.ApiServiceInterceptor"></bean>
</mvc:interceptors>
<!--To Enable @Value to map key with provided fields for property files -->
<context:property-placeholder />
Spring-servlet.xmlとapplicationContext.xmlの2つの場所でパッケージをスキャンする必要がなくなります
デバッグに時間がかかったものを追加します。@ Transactionalアノテーションは「パブリック」メソッドでのみ機能することを忘れないでください。
「保護された」ものに@Transactionalを配置すると、このエラーが発生しました。
それが役に立てば幸い :)
http://docs.spring.io/spring/docs/3.1.0.M2/spring-framework-reference/html/transaction.html
メソッドの可視性と@Transactional
プロキシを使用する場合、@ Transactionalアノテーションは、パブリック可視性を持つメソッドにのみ適用する必要があります。保護されたメソッド、プライベートメソッド、またはパッケージに表示されるメソッドに@Transactionalアノテーションを付けた場合、エラーは発生しませんが、アノテーション付きメソッドは構成済みのトランザクション設定を示しません。非パブリックメソッドに注釈を付ける必要がある場合は、AspectJ(以下を参照)の使用を検討してください。
私はこれがある程度の年齢の質問であることを知っていますが、この問題にぶつかり、Spring-Java構成を使用している場合、解決にはいくつかの部分があることがわかりました。コントローラへのいくつかの構成の相対的な配置が重要でした。
まず、CoreConfiguration
@Configuration
public class CoreConfiguration {
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean factoryBean = new org.springframework.orm.hibernate4.LocalSessionFactoryBean();
String annotatedPckgs[] ={"org.tigersndragons.reports.model.warehouse"};
factoryBean.setAnnotatedPackages(annotatedPckgs);
Properties hibernateProperties = new Properties();
try {
hibernateProperties.load(this.getClass().getResourceAsStream("props/hibernate.properties"));
factoryBean.setHibernateProperties(hibernateProperties);
} catch (IOException e) { }
factoryBean.setPackagesToScan("org.telligen.reports.model.warehouse");
factoryBean.setDataSource(warehouseDataSource());//("jdbc/warehouse");
try {
factoryBean.afterPropertiesSet();
} catch (IOException e) { }
return factoryBean;
}
@Bean
public WarehouseDAO getWarehouseDAO(){
WarehouseDAO wrhsDao = new WarehouseDAO();
wrhsDao.setSessionFactory(sessionFactory().getObject());
return wrhsDao;
}
...
@Configuration
public class ScheduleConfiguration {
private static Logger logger = LoggerFactory.getLogger(ScheduleConfiguration.class);
@Autowired
private CoreConfiguration coreConfiguration;
@Bean
public HandlerMapping handlerMapping(){
DefaultAnnotationHandlerMapping mapping = new DefaultAnnotationHandlerMapping();
mapping.setInterceptors(new Object []{coreConfiguration.openSessionViewInterceptor()});
return mapping;
}
@Bean
public HandlerAdapter handerAdapter(){
return new AnnotationMethodHandlerAdapter();
}
@Bean
public ScheduleController scheduleController() throws Exception{
ScheduleController controller = new ScheduleController();
controller.setWrhsDao(coreConfiguration.getWarehouseDAO());
return controller;
}
...
コントローラーでは、設定する必要がありました
@Controller
@RequestMapping
public class ScheduleController {
private static Logger logger = LoggerFactory.getLogger(ScheduleController.class);
private WarehouseDAO wrhsDao;
@RenderMapping
@RequestMapping("VIEW")
public String viewSchedule(Map<String, Object> modelMap){...}
public void setWrhsDao(WarehouseDAO wrhsDao) {
this.wrhsDao = wrhsDao;
}
}
WarehouseDAOには@Repository注釈があり、SessionFactoryは自動配線されていません。
これが同様の質問で他の誰かを助けることを願っています。