tutorial mvc gratis framework español curso spring hibernate sessionfactory

mvc - Spring e hibernate: no se encontró ninguna sesión para el hilo actual



spring mvc 4 tutorial español (6)

Añadiré algo que me llevó algún tiempo depurar: no olvide que una anotación @Transactional solo funcionará en métodos "públicos".

Puse algunos @Transactional en los "protegidos" y obtuve este error.

Espero eso ayude :)

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

Visibilidad del método y @Transactional

Al usar proxies, debe aplicar la anotación @Transactional solo a los métodos con visibilidad pública. Si anota métodos protegidos, privados o visibles del paquete con la anotación @Transactional, no se genera ningún error, pero el método anotado no muestra la configuración transaccional configurada. Considere el uso de AspectJ (ver a continuación) si necesita anotar métodos no públicos.

estoy obteniendo el siguiente error

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)

Clase de servicio

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

poco de clase 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; }

y tengo esto en mi 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>

¿Alguien puede ver por qué estoy recibiendo el siguiente error?


Anotaste tu clase Dao con @Transactional, pero no tu clase de servicio. La línea:

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

requiere que estés en una transacción.

Puede solucionar esto agregando la anotación @Transactional a su clase ProfileService, o simplemente el método registerVisitor ().


Resolví el mismo problema con los siguientes 2 pasos

  1. @Transactional en el método de servicio como se sugiere jordan002 en su respuesta en esta página.

  2. Una cosa más, si tiene 2 archivos de configuración: por ejemplo, application-context.xml (para configuración específica de contexto de aplicación y DB) y webmvc-context.xml (para configuración específica de web / controlador), entonces debe escanear los paquetes diferentes para su controladores y dao.

    El webmvc-context.xml se carga después de application-context.xml . Creo que la clase DAO se carga primero con referencias transaccionales cuando se carga el application-context.xml, pero se reemplaza con otro objeto, sin referencias transaccionales, cuando se carga webmvc-context.xml.

    De cualquier forma, resuelvo el problema con paquetes específicos escaneados:

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

    para application-context.xml

    y

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

    para webmvc-context.xml .


Resolví el problema anterior siguiendo dos pasos

1-Adición de soporte @Transactional en mi método de servicio que está llamando a métodos DAO

2-Al importar el applicationContext.xml en spring-servlet.xml de esta manera

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

Elimina la necesidad de escanear paquetes en dos lugares: spring-servlet.xml y applicationContext.xml


Sé que esta es una pregunta con cierta antigüedad, pero me encontré con este problema y descubrí que si está utilizando la configuración Spring-Java, una resolución tenía un par de partes. La colocación relativa de alguna configuración en el controlador fue importante.

En primer lugar, 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; } ...

En el controlador, tuve que configurar

@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 tiene la anotación @Repository y SessionFactory no estaba Autowired.

Espero que esto ayude a alguien más con preguntas similares.


cambie la anotación de su DAO con @Repository

@Repository public class ProfileDao { . . . }

y luego crea tu método de servicio @Transactional por ejemplo, así

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