2012-04-24 18 views
20

im gettting il seguente erroreprimavera e ibernazione: nessuna sessione trovata per thread corrente

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) 

La classe di servizio

@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); 

    } 
} 

po 'di classe 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; 
    } 

e ho questo in my 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> 

qualcuno può individuare perché sto ottenendo il seguente errore?

+0

delle jordan002 è corretto, ma il problema "reale" è che invece di chiamare DAO nel vostro servizio, si accede DB dalla classe di servizio ... D'altra parte, in genere, si desidera che il metodo di servizio si comporti a livello transazionale invece dei soli metodi DAO: se si dispone di 2 aggiornamenti nel metodo di servizio e il secondo non riesce, le transazioni non consentono di avere un DB coerente (ma dipende dalla logica aziendale) . – Betlista

risposta

40

Hai annotato la tua classe Dao con @Transactional, ma non la tua classe di servizio. La riga:

Visitor storedVisitor = 
    (Visitor) sessionFactory.getCurrentSession().get(Visitor.class, 
      visitorDetails.getTfscNumber(), LockMode.NONE); 

richiede di essere in una transazione.

È possibile risolvere questo problema aggiungendo l'annotazione @Transactional alla classe ProfileService o semplicemente al metodo registerVisitor().

+0

Questo va oltre e aiuta a mettersi in letargo per scrivere aggiornamenti/eliminazioni. – iowatiger08

5

cambiare la vostra annotazione DAO s' con @Repository

@Repository 
public class ProfileDao { 
. 
. 
. 
} 

e quindi rendere il vostro metodo di servizio @Transactional per esempio come questo

@Transactional 
public List<Retailer> getRetailerByRetailerNumber(String retailerNo) {} 
9

ho risolto lo stesso problema con i seguenti 2 passi

  1. Posizionato @Transactional sul metodo di servizio come suggerito jordan002 nella sua risposta su questa pagina.

  2. più una cosa, se si dispone di 2 file di configurazione: dicono application-context.xml (per DB e specifico contesto applicativo di configurazione ) e webmvc-context.xml (per web/regolatore specifica configurazione ), allora si dovrebbe eseguire la scansione dei diversi pacchetti per la vostra controllori e dao.

    Il webmvc-context.xml viene caricato dopo application-context.xml. Penso che la classe DAO sia caricata prima con i riferimenti transazionali quando l'application-context.xml è caricato, ma è sostituito con un altro oggetto, senza riferimenti transazionali, quando viene caricato webmvc-context.xml.

    Qualsiasi modo, risolvo il problema con i pacchetti specifici esaminati:

    <context:component-scan base-package="com.app.repository" /> 
    

    per application-context.xml

    e

    <context:component-scan base-package="com.app.web" /> 
    

    per webmvc-context.xml.

1

So che questa è una domanda con una certa età, ma mi sono imbattuto in questo problema e ha scoperto che se si utilizza la configurazione Primavera-Java, che una risoluzione ha avuto un paio di parti di questo. Il posizionamento relativo di alcune configurazioni al controller era importante.

In primo luogo, il 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; 
} 

... 

Nel Controller, ho dovuto impostare

@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; 
} 
} 

Il WarehouseDAO ha l'annotazione @Repository e la SessionFactory non era Autowired.

Spero che questo aiuti qualcun altro con domande simili.

0

Aggiungo solo qualcosa che mi ha richiesto un po 'di tempo per eseguire il debug: non dimenticare che un'annotazione @Transactional funziona solo con metodi "pubblici".

Ho messo alcuni @Transactional su quelli "protetti" e ho ricevuto questo errore.

Speranza che aiuta :)

http://docs.spring.io/spring/docs/3.1.0.M2/spring-framework-reference/html/transaction.html

visibilità Metodo e @Transactional

Quando si utilizza proxy, si dovrebbe applicare l'annotazione @Transactional solo ai metodi con visibilità pubblica. Se si annotano i metodi protetti, private o package-visible con l'annotazione @Transactional, , non viene generato alcun errore, ma il metodo annotato non mostra le impostazioni transazionali configurate per . Considerare l'uso di AspectJ (vedi qui sotto) se è necessario annotare metodi non pubblici.

2

ho risolto il problema precedente seguendo due step

1-Aggiunta del supporto @Transactional nel mio metodo di servizio che è chiamata metodi DAO

2-importando l'applicationContext.xml in primavera-servlet .xml in questo modo

<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 /> 

Si elimina la necessità di eseguire la scansione di confezione età in due luoghi primavera-servlet.xml e applicationContext.xml

risposta
Problemi correlati