2013-04-04 1 views
0

Много подобных, но не одинаковых проблем, поэтому я не смог найти решение для этого.TransactionRequiredException весной webmvc framework

У меня есть Spring + JPA (Hibernate) веб-приложение.

конфигурации контекста (данные-context.xml):

<?xml version="1.0" encoding="UTF-8"?> 
<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:jdbc="http://www.springframework.org/schema/jdbc" 
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.2.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.2.xsd 
    http://www.springframework.org/schema/jdbc 
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="org.postgresql.Driver"/> 
    <property name="url" value="jdbc:postgresql://localhost:5432/db"/> 
    <property name="username" value="postgres"/> 
    <property name="password" value="1234"/> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="emf"/> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> 
    </property> 
    <property name="packagesToScan" value="com.myapp.mvc.logic.domain"/> 
    <property name="jpaProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> 
      <prop key="hibernate.max_fetch_depth">3</prop> 
      <prop key="hibernate.jdbc.fetch_size">50</prop> 
      <prop key="hibernate.jdbc.batch_size">10</prop> 
      <prop key="hibernate.show_sql">true</prop> 
     </props> 
    </property> 
</bean> 

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> 

<context:annotation-config/> 

<context:component-scan base-package="com.myapp.mvc.logic" /> 

конфигурации DispetcherServlet (сервлет-context.xml):

<?xml version="1.0" encoding="UTF-8"?> 
<beans:beans xmlns="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:beans="http://www.springframework.org/schema/beans" 
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:security="http://www.springframework.org/schema/security" 
xsi:schemaLocation="http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.2.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd 
    ">  

<annotation-driven validator="validator"/> 

<resources mapping="/resources/**" location="/resources/" /> 

<default-servlet-handler/> 

<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver"> 
    <beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/> 
</beans:bean> 

<beans:bean class="org.springframework.web.servlet.view.tiles3.TilesConfigurer" id="tilesConfigurer"> 
    <beans:property name="definitions"> 
     <beans:list> 
      <beans:value>/WEB-INF/layouts/layouts.xml</beans:value> 
      <beans:value>/WEB-INF/views/**/views.xml</beans:value> 
     </beans:list> 
    </beans:property> 
</beans:bean> 

<interceptors> 
    <beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/> 
</interceptors> 

<beans:bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" 
      id="messageSource" 
      p:basenames="classpath:META-INF/i18n/application, classpath:META-INF/i18n/validation_messages" 
      /> 
<beans:bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" 
      id="localeResolver" 
      p:cookieName="locale"/> 

<beans:bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 
    <beans:property name="validationMessageSource" ref="messageSource"/> 
</beans:bean> 

<context:component-scan base-package="com.myapp.mvc" /> 

Контроллер:

@RequestMapping("/users") 
@Controller 
public class BankAccountCatalogController { 

@Inject 
private Functions functions; 

@RequestMapping(value="/update", method = RequestMethod.POST) 
public String catalogBankAccountUpdate(Model uiModel) { 
    functions.addUser(); 
    return "employee_cabinet/catalog_bank_account"; 
} 
} 

Functions.class:

@Service("functions") 
@Repository 
@Transactional 
public class Functions { 

@PersistenceContext 
private EntityManager em; 

@Transactional 
public void addUser() { 
    User user = new User(); 
    user.setFirstName("John"); 
    user.setLastName("John"); 
    user.setMiddleName("John"); 
    user.setEmail("[email protected]"); 
    user.setPhone(null); 
    user.setMd5Password("1234"); 
    em.persist(user); 
    em.flush(); 
} 
} 

Когда я активировать контроллер, в em.flush(); линии я получаю сообщение об ошибке:

javax.persistence.TransactionRequiredException: no transaction is in progress 

По некоторым причинам сделки не активны в addUser() функции. Я попытался запустить функцию в среде JUnit - она ​​работает нормально. Любые идеи?

+0

http://stackoverflow.com/questions/7272354/why-do-we-have-to-manually-flush-the-entitymanager-in-a-extended-persistenceco# –

+0

@Baadshah Как это могло помочь в моей проблеме? –

ответ

1

Решено. Это была неправильная конфигурация DispetcherServlet.

Вместо

<context:component-scan base-package="com.myapp.mvc" /> 

в сервлет-context.xml, я написал

<context:component-scan base-package="com.myapp.mvc.web.controller" /> 

и она работает.

Полезная тема: Spring @Transactional - javax.persistence.TransactionRequiredException

1

Попробуйте удалить EntityManager с контроллера, указав метод как транзактный на контроллере.

@RequestMapping("/users") 
@Controller 
public class BankAccountCatalogController { 

@Inject 
private Functions functions; 

@RequestMapping(value="/update", method = RequestMethod.POST) 
@Transactional 
public String catalogBankAccountUpdate(Model uiModel) { 
    functions.addUser(); 
    return "employee_cabinet/catalog_bank_account"; 
} 
} 

сделать Также убедитесь, что Functions класс указан в пакетах вы компонент сканирования, который com.dominform.mvc.logic.

<context:component-scan base-package="com.dominform.mvc.logic" />