2012-04-24 5 views
20

им gettting следующее сообщение об ошибкеВесна и спящий режим: Нет сеансов найдено для текущего потока

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

и у меня есть это 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> 

может кто-нибудь заметить, почему я получаю следующее сообщение об ошибке?

+0

Ответы jordan002 верны, но «настоящая» проблема заключается в том, что вместо вызова DAO в вашем сервисе вы получаете доступ к базе данных из класса обслуживания ... С другой стороны, обычно вы хотите, чтобы метод службы вел себя транзакционно, а не только методы DAO - если у вас есть 2 обновления в методе службы, а во втором - нет, транзакции не помогут вам согласовать БД (но это зависит от вашей бизнес-логики) , – Betlista

ответ

40

Вы аннулировали свой класс Dao с помощью @Transactional, но не ваш класс обслуживания. Линия:

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

требует, чтобы вы были в сделке.

Вы можете исправить это, добавив аннотацию @Transactional к вашему классу ProfileService или просто к методу registerVisitor().

+0

Это идет дальше и помогает с получением hibernate для записи обновлений/удалений. – iowatiger08

5

изменить ваш аннотацию DAO «s с @Repository

@Repository 
public class ProfileDao { 
. 
. 
. 
} 

, а затем сделать свой метод сервиса @Transactional, например, как этот

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

я решил такую ​​же проблему со следующими 2 шагах

  1. Размещено @Transactional по способу обслуживания, как предложено jordan002 в его ответе на этой странице.

  2. Еще одна вещь, если у вас есть 2 конфигурационные файлы: говорят application-context.xml (для БД и контекст Application Specific конфигурации) и webmvc-context.xml (для веб/контроллера конкретных конфигурации), то вы должны сканировать пакеты различных для вашего контроллеры и дао.

    webmvc-context.xml загружен после application-context.xml. Я думаю, что класс DAO загружается сначала с транзакционными ссылками при загрузке приложения-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.

1

Я знаю, что это вопрос с каким-то возрастом, но я столкнулся с этим вопросом и обнаружил, что если вы используете конфигурацию 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 не было Авто.

Надеюсь, это поможет кому-то еще с подобными вопросами.

0

Я просто добавлю что-то, что заняло некоторое время для отладки: не забывайте, что аннотация @Transactional будет работать только на «общедоступных» методах.

Я положил некоторый @Transactional на «защищенные» и получил эту ошибку.

Надеется, что это помогает

Методу видимости :)

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

и @Transactional

При использовании прокси, вы должны применять аннотацию @Transactional только к методам с информированием общественности. Если вы делаете аннотацию защищенных, частных или видимых с помощью пакетов методов с аннотацией @Transactional, , никакая ошибка не возникает, но аннотированный метод не отображает настроенные транзакционные настройки . Рассмотрим использование AspectJ (см. Ниже ), если вам необходимо аннотировать непубличные методы.

2

Я решил вышеуказанную проблему, выполнив два шаг

1-Добавление @Transactional поддержки в моем методе обслуживания, который вызов методов DAO

2-Путем импорт applicationContext.xml в весенне-сервлете .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

Смежные вопросы