Code Bye

Spring的事务管理无法持久化到数据库中

利用Spring的事务管理无法将数据写到数据库中啊
下面是我的代码:
applicationContext.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:tx="http://www.springframework.org/schema/tx"
    default-autowire="byName" xmlns:mvc="http://www.springframework.org/schema/mvc"
    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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- 自动扫描的包名 -->
	<context:component-scan base-package="com.github.Yasenia.flea_school.server">
	</context:component-scan>

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

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

	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="fleaSchool" />
		<property name="jpaDialect" ref="jpaDialect"/> 
	</bean>

	<bean id="jpaDialect" 
		class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> 
</beans>

springMVC-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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" default-autowire="byName"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- 自动扫描的包名 -->
	<context:component-scan base-package="com.github.Yasenia.flea_school.server">
	</context:component-scan>

	<!-- 默认的注解映射的支持 -->
	<mvc:annotation-driven />

	<!-- 视图解释类 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>


	<!-- 对静态资源文件的访问 方案 -->
	<mvc:default-servlet-handler />
</beans>

IUserDAOImpl.java

@Named
public class UserDAOImpl implements IUserDAO {

    @PersistenceContext
    private EntityManager em;

    public void save(User user) {
        em.persist(user);
    }
    ...
}

IUserService.java:

@Named
public class UserServiceImpl implements IUserService {
    @Inject
    private IUserDAO userDAO;
    

    @Transactional(propagation = Propagation.REQUIRED)
    public void save(User user) {
        user.setRegisterDate(new Date());
        userDAO.save(user);
    }
}

我手动开启和提交事务也不行

    public void save(User user) {
        System.out.println("userDAO working");
        EntityTransaction transaction = em.getTransaction(); 
        transaction.begin();
        System.out.println("userDAO saving");
        System.out.println("em is: " + em);
        em.persist(user);
        transaction.commit();

    }

执行到EntityTransaction transaction = em.getTransaction();这句话就会退出方法。

不知道是什么原因,求大神指点啊!

获取事务那里退出,是日志提示还是断点跟到那中断了?有没有报错之类的?

5分
默认情况下,spring事务管理中如果碰到RuntimeException,事务就会回滚,你catch一下,看有没有报错
引用 1 楼 oh_Maxy 的回复:

获取事务那里退出,是日志提示还是断点跟到那中断了?有没有报错之类的?

断点跟到那里中断的!

引用 2 楼 yonghudengluzhonging 的回复:

默认情况下,spring事务管理中如果碰到RuntimeException,事务就会回滚,你catch一下,看有没有报错

捕捉了一下没有异常
事务还没有开始,在手动加载事务的测试里面,执行到EntityTransaction transaction = em.getTransaction(); 这句话后,后面的语句就没执行了,方法就结束了。

引用 4 楼 moliqinmicha 的回复:
Quote: 引用 2 楼 yonghudengluzhonging 的回复:

默认情况下,spring事务管理中如果碰到RuntimeException,事务就会回滚,你catch一下,看有没有报错

捕捉了一下没有异常
事务还没有开始,在手动加载事务的测试里面,执行到EntityTransaction transaction = em.getTransaction(); 这句话后,后面的语句就没执行了,方法就结束了。

那你不使用事务,是不是就正确入库了?
另外,断点跟到这里,em对象是否为空?

引用 6 楼 oh_Maxy 的回复:
Quote: 引用 4 楼 moliqinmicha 的回复:
Quote: 引用 2 楼 yonghudengluzhonging 的回复:

默认情况下,spring事务管理中如果碰到RuntimeException,事务就会回滚,你catch一下,看有没有报错

捕捉了一下没有异常
事务还没有开始,在手动加载事务的测试里面,执行到EntityTransaction transaction = em.getTransaction(); 这句话后,后面的语句就没执行了,方法就结束了。

那你不使用事务,是不是就正确入库了?
另外,断点跟到这里,em对象是否为空?

em不为空
不开启事务也能持久化么。。。我刚学JPA,好像必须要在事务中才能进行持久化操作,不然操作无效的


10分
引用 7 楼 moliqinmicha 的回复:
Quote: 引用 6 楼 oh_Maxy 的回复:
Quote: 引用 4 楼 moliqinmicha 的回复:
Quote: 引用 2 楼 yonghudengluzhonging 的回复:

默认情况下,spring事务管理中如果碰到RuntimeException,事务就会回滚,你catch一下,看有没有报错

捕捉了一下没有异常
事务还没有开始,在手动加载事务的测试里面,执行到EntityTransaction transaction = em.getTransaction(); 这句话后,后面的语句就没执行了,方法就结束了。

那你不使用事务,是不是就正确入库了?
另外,断点跟到这里,em对象是否为空?

em不为空
不开启事务也能持久化么。。。我刚学JPA,好像必须要在事务中才能进行持久化操作,不然操作无效的

太诡异了,表示爱莫能助。。。

@PersistenceContext
    private EntityManager em;

注解是这么设置的么

引用 9 楼 whos2002110 的回复:
@PersistenceContext
    private EntityManager em;

注解是这么设置的么

是的, 没看见你那段代码

把DAO类上的注解换成@Repository试下
这个我遇到过
引用 12 楼 u013679475 的回复:

这个我遇到过

求教怎么解决的~

异常捕获此行代码,控制台异常一目了然

 EntityTransaction transaction = em.getTransaction(); 


20分
我看到你在applicationContext.xml和springMVC-servlet.xml两个xml中都有 <context:component-scan base-package=”com.github.Yasenia.flea_school.server”></context:component-scan>,表示都会去扫描所有的类,不知道你在web.xml里面是现在加载的哪一个xml?在首先加载的xml里面,不要去扫描DAO里面的类,不然事务就会失效!
不懂,目测事务管理配置问题。
你的事务管理器呢..
引用 15 楼 s373891831 的回复:

我看到你在applicationContext.xml和springMVC-servlet.xml两个xml中都有 <context:component-scan base-package=”com.github.Yasenia.flea_school.server”></context:component-scan>,表示都会去扫描所有的类,不知道你在web.xml里面是现在加载的哪一个xml?在首先加载的xml里面,不要去扫描DAO里面的类,不然事务就会失效!

谢谢,我已经解决了,在servlet.xml里面只扫描controller,在applicationContext.xml里面扫描其它组件就行了。

引用 20 楼 moliqinmicha 的回复:
Quote: 引用 15 楼 s373891831 的回复:

我看到你在applicationContext.xml和springMVC-servlet.xml两个xml中都有 <context:component-scan base-package=”com.github.Yasenia.flea_school.server”></context:component-scan>,表示都会去扫描所有的类,不知道你在web.xml里面是现在加载的哪一个xml?在首先加载的xml里面,不要去扫描DAO里面的类,不然事务就会失效!

谢谢,我已经解决了,在servlet.xml里面只扫描controller,在applicationContext.xml里面扫描其它组件就行了。

学习了,以前也知道是这么用的,但不知道所以然。是否是动态代理惹的祸?

以前也遇到这样的问题,贴出来,大家一起学习:
Spring MVC启动时的配置文件,包含组件扫描、url映射以及设置freemarker参数,让spring不扫描带有@Service注解的类。为什么要这样设置?因为servlet-context.xml与service-context.xml不是同时加载,如果不进行这样的设置,那么,spring就会将所有带@Service注解的类都扫描到容器中,等到加载service-context.xml的时候,会因为容器已经存在Service类,使得cglib将不对Service进行代理,直接导致的结果就是在service-context中的事务配置不起作用,发生异常时,无法对数据进行回滚。
加try catch 处理一下,看看是什么异常 
引用 22 楼 lf_can 的回复:

以前也遇到这样的问题,贴出来,大家一起学习:
Spring MVC启动时的配置文件,包含组件扫描、url映射以及设置freemarker参数,让spring不扫描带有@Service注解的类。为什么要这样设置?因为servlet-context.xml与service-context.xml不是同时加载,如果不进行这样的设置,那么,spring就会将所有带@Service注解的类都扫描到容器中,等到加载service-context.xml的时候,会因为容器已经存在Service类,使得cglib将不对Service进行代理,直接导致的结果就是在service-context中的事务配置不起作用,发生异常时,无法对数据进行回滚。

原来这里也要注意,以前没遇到过,学习了。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Spring的事务管理无法持久化到数据库中