Сессия Hibernate не связана с потоком - PullRequest
1 голос
/ 14 сентября 2010

Я использую Spring MVC и Hibernate.

Я хочу использовать OpenSessionInViewFilter для корректной работы отложенной загрузки в слое представления.

OpenSessionInViewFilter требует контекст корневого приложения, поэтому ядобавил ContextLoaderListener и переместил мои файлы конфигурации, не связанные с просмотром, в него из DispatcherServlet.

Файл конфигурации app-config.xml содержит bean-компоненты, связанные с источником данных.

Когда я загружаю app-config.xml, используя ContextLoaderListener вместо DispatcherServlet, я получаю сообщение об ошибке

WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/XXXX/app/jobs] in DispatcherServlet with name 'Spring MVC Dispatcher Servlet'

ОБНОВЛЕНИЕ: исправлена ​​эта ошибка путем добавления компонента сканирования в mvc-config.xml

, но теперь я получаю

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

Насколько я понимаю, DispatcherServlet наследует bean-компоненты из корневого контекста, поэтому перемещение определений из сервлета в корневой контекст не должно иметь значения.

web.xml

<filter>
  <filter-name>UrlRewriteFilter</filter-name>
  <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>UrlRewriteFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <filter>
  <filter-name>openSessionInViewFilter</filter-name>
  <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
  <init-param>
   <param-name>singleSession</param-name>
   <param-value>true</param-value>
  </init-param>
  <init-param>
   <param-name>flushMode</param-name>
   <param-value>AUTO</param-value>
  </init-param>
  <init-param>
   <param-name>sessionFactoryBeanName</param-name>
   <param-value>sessionFactory</param-value>
  </init-param>
 </filter>

 <filter-mapping>
  <filter-name>openSessionInViewFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   /WEB-INF/spring/app-config.xml
   /WEB-INF/spring/other-config.xml
  </param-value>
 </context-param>

 <!-- Handles all requests into the application -->
 <servlet>
  <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>
    /WEB-INF/spring/mvc-config.xml
   </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <!-- Maps all /app requests to the DispatcherServlet for handling -->
 <servlet-mapping>
  <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
  <url-pattern>/app/*</url-pattern>
 </servlet-mapping>

app-config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

 <!--
  Scans within the base package of the application for @Components to
  configure as beans
 -->
 <context:component-scan base-package="com.mycompany.app" />

 <!-- SQL Server -->
 <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource"
  destroy-method="close">
  <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
  <property name="url" value="jdbc:jtds:sqlserver://x.x.x.x/XXX" />
  <property name="username" value="XXX" />
  <property name="password" value="XXX" />
 </bean>

 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource" ref="datasource" />
  <property name="configLocation">
   <value>/WEB-INF/hibernate.cfg.xml</value>
  </property>
  <property name="configurationClass">
   <value>org.hibernate.cfg.AnnotationConfiguration</value>
  </property>
  <property name="hibernateProperties">
   <value>hibernate.dialect=org.hibernate.dialect.SQLServerDialect</value>
  </property>
 </bean>

 <tx:annotation-driven />

 <bean name="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>

</beans>

mvc-config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<!-- Configures support for @Controllers -->
<mvc:annotation-driven />

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

 <bean id="tilesConfigurer"
  class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
  <property name="definitions">
   <list>
    <value>/WEB-INF/defs/general.xml</value>
   </list>
  </property>
 </bean>

 <bean id="viewResolver"
  class="org.springframework.web.servlet.view.UrlBasedViewResolver">
  <property name="viewClass"
   value="org.springframework.web.servlet.view.tiles2.TilesView" />
 </bean>

</beans>

Ответы [ 2 ]

4 голосов
/ 14 сентября 2010

Одна из возможных проблем, которую я вижу здесь, заключается в том, что openSessionInViewFilter отображается после UrlRewriteFilter. UrlRewriteFilter выполняет RequestDispatcher.forward(), поэтому все фильтры, отображаемые после него, должны иметь <dispatcher>FORWARD</dispatcher>:

<filter-mapping> 
    <filter-name>openSessionInViewFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    <dispatcher>FORWARD</dispatcher>
</filter-mapping> 
0 голосов
/ 14 сентября 2010

<tx:annotation-driven /> охватывает только локальный контекст, в котором он определен. В этом случае он покроет компоненты в app-config.xml, так как это единственное место, где я вижу его в вашей конфигурации.

В зависимости от того, где определены ваши транзакции (и исходя из вашей ошибки, я предполагаю, что они определены в bean-компонентах в контексте mvc-config.xml), это может привести к классам или методам @Transactional, которые не связаны с управлением транзакциями Spring.

Полагаю, вам нужно добавить <tx:annotation-driven /> в ваш mvc-config.xml.

Ниже приводится справка Spring :

<tx:annotation-driven/> ищет только @Transactional на бобах в том же контекст приложения, в котором он определен. Это означает, что если вы положите <tx:annotation-driven/> в WebApplicationContext для DispatcherServlet, он проверяет только @Transactional бобов в вашем контроллеры, а не ваши услуги. См. Раздел 15.2 « ДиспетчерСервлет » для более информация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...