spring – 没有实际交易可用于当前线程的EntityManager – 不能可靠地处理“持续”呼叫
我试图调用“持久”方法来保存实体模型到我的Spring MVC Web应用程序中的数据库时,出现此错误。 在互联网上找不到任何可能与此特定错误有关的post或页面。 这看起来像EntityManagerFactory bean的东西是错误的,但我是相当新的spring编程,所以对于我来说,似乎一切都很好初始化,根据各种教程的文章在networking上。
调度员servlet.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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository-1.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd"> <context:component-scan base-package="wymysl.Controllers" /> <jpa:repositories base-package="wymysl.repositories"/> <context:component-scan base-package="wymysl.beans" /> <context:component-scan base-package="wymysl.Validators" /> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> <bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/> <bean id="passwordValidator" class="wymysl.Validators.PasswordValidator"></bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="username" value="system" /> <property name="password" value="polskabieda1" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml" /> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" /> <property name="showSql" value="true" /> <property name="generateDdl" value="false" /> </bean> </property> <property name="jpaProperties"> <props> <prop key="hibernate.max_fetch_depth">3</prop> <prop key="hibernate.jdbc.fetch_size">50</prop> <prop key="hibernate.jdbc.batch_size">10</prop> </props> </property> </bean> <mvc:annotation-driven /> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:messages" /> </bean> <bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <mvc:resources mapping="/resources/**" location="/resources/" /> <mvc:resources mapping="/resources/*" location="/resources/css/" cache-period="31556926"/> </beans>
RegisterController.java
@Controller public class RegisterController { @PersistenceContext EntityManager entityManager; @Autowired PasswordValidator passwordValidator; @InitBinder private void initBinder(WebDataBinder binder) { binder.setValidator(passwordValidator); } @RequestMapping(value = "/addUser", method = RequestMethod.GET) public String register(Person person) { return "register"; } @RequestMapping(value = "/addUser", method = RequestMethod.POST) public String register(@ModelAttribute("person") @Valid @Validated Person person, BindingResult result) { if(result.hasErrors()) { return "register"; } else { entityManager.persist(person); return "index"; } }
我有同样的问题,我注释了@Transactional
的方法,它的工作。
更新:检查Spring文档默认情况下,PersistenceContexttypes为Transaction,所以这就是为什么该方法必须是事务性的( http://docs.spring.io/spring/docs/current/spring-framework-reference/ html / orm.html ):
@PersistenceContext注释具有可选的属性types,默认为PersistenceContextType.TRANSACTION。 这个默认是你需要接收一个共享的EntityManager代理。 另一种方法是PersistenceContextType.EXTENDED,这是一个完全不同的事情:这导致了一个所谓的扩展的EntityManager,它不是线程安全的,因此不能在同时访问的组件中使用,例如Springpipe理的单例bean。 扩展的EntityManagers只能用在有状态的组件中,例如,驻留在一个会话中,而EntityManager的生命周期不与当前事务绑定,而是完全由应用程序决定。
在尝试在Spring数据存储库中使用deleteBy自定义方法时遇到此exception。 该操作是从JUnittesting课程中尝试的。
在JUnit类级别使用@Transactional
注释时,不会发生exception。
这个错误让我f了三天,我面临的情况也产生了同样的错误。 遵循所有的build议,我可以find,我玩的configuration,但无济于事。
最终我发现它,不同的是,我执行的服务被包含在一个普通的jar中,问题原来是AspectJ没有对待Service实例化。 实际上,代理只是在方法调用之前调用底层方法而没有执行所有正常的Spring魔法。
最后,根据示例放置在服务上的@Scope注释解决了这个问题:
@Service @Scope(proxyMode = ScopedProxyMode.INTERFACES) @Transactional public class CoreServiceImpl implements CoreService { @PersistenceContext protected EntityManager entityManager; @Override public final <T extends AbstractEntity> int deleteAll(Class<T> clazz) { CriteriaDelete<T> criteriaDelete = entityManager.getCriteriaBuilder().createCriteriaDelete(clazz); criteriaDelete.from(clazz); return entityManager.createQuery(criteriaDelete).executeUpdate(); } }
我发布的方法是一个删除方法,但注释以同样的方式影响所有的持久性方法。
我希望这篇文章可以帮助别人从jar中加载服务时遇到同样的问题
我有同样的错误,因为我从XML切换到Javaconfiguration。
关键是,我没有像冯石build议的那样移植<tx:annotation-driven/>
标签。
所以我刚刚添加@EnableTransactionManagement
build议在这里build立在@Configuration类Spring中的Annotation驱动事务 ,它现在工作
我有同样的问题,我在applicationContext.xml中添加tx:注解驱动,它的工作。
对于我们来说,问题归结为多个configuration文件中相同的上下文设置。 检查你没有在多个configuration文件中重复以下内容。
<context:property-placeholder location="classpath*:/module.properties"/> <context:component-scan base-package="...." />
我从中删除了模式
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
做这个工作