web-dev-qa-db-fra.com

Spring et hibernate: Aucune session trouvée pour le thread actuel

im obtenir l'erreur suivante

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)

Classe de service

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

    }
}

peu de 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;
    }

et je l'ai dans mon 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>

quelqu'un peut-il comprendre pourquoi j'obtiens l'erreur suivante?

21
Hip Hip Array

Vous avez annoté votre classe Dao avec @Transactional, mais pas votre classe de service. La ligne:

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

vous oblige à être dans une transaction.

Vous pouvez résoudre ce problème en ajoutant l'annotation @Transactional à votre classe ProfileService ou simplement la méthode registerVisitor ().

44
Peter Bratton

J'ai résolu le même problème en suivant les 2 étapes

  1. Placé @Transactional sur la méthode de service suggérée jordan002 dans sa réponse sur cette page.

  2. Encore une chose, si vous avez 2 fichiers de configuration: dites application-context.xml (Pour la configuration spécifique au DB et au contexte d'application) et webmvc-context.xml (Pour la configuration spécifique au Web/contrôleur), vous devez alors analyser les packages différents pour vos contrôleurs et dao.

    Le webmvc-context.xml est chargé après application-context.xml. Je pense que la classe DAO est chargée en premier avec des références transactionnelles lorsque l'application-context.xml est chargée, mais elle est remplacée par un autre objet, sans références transactionnelles, lorsque webmvc-context.xml est chargé.

    Quoi qu'il en soit, je résous le problème avec des packages spécifiques numérisés:

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

    pour application-context.xml

    et

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

    pour webmvc-context.xml.

11
Arun Kumar

changer l'annotation de votre DAO avec @Repository

@Repository
public class ProfileDao { 
.
.
.
}

puis faites votre méthode de service @Transactional par exemple comme ceci

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

J'ai résolu le problème ci-dessus en suivant deux étapes

1-Ajout du support @Transactional dans ma méthode de service qui appelle des méthodes DAO

2-En important le fichier applicationContext.xml dans spring-servlet.xml de cette manière

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

Il supprime la nécessité d'analyser les packages à deux endroits spring-servlet.xml et applicationContext.xml

3
pintu

Je sais que c'est une question avec un certain âge, mais j'ai rencontré ce problème et j'ai constaté que si vous utilisez la configuration Spring-Java, une résolution comportait plusieurs parties. Le placement relatif d'une certaine configuration par rapport au contrôleur était important.

Tout d'abord, la 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;
}

 ...

Dans le contrôleur, je devais définir

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

Le WarehouseDAO a l'annotation @Repository et SessionFactory n'était pas Autowired.

J'espère que cela aide quelqu'un d'autre avec des questions similaires.

1
iowatiger08