0

My project encountered the problem that Spring JPA transactions would not roll back. The project framework is spring MVC + Spring + spring data JPA + oracle. I searched a lot of information on the Internet, but still could not solve my problem.

I've tried many ways, such as setting the method to public or adding rollbackFor = Exception.class in @Transactional, but it still can't be solved.

Here's my code

Controller

@RequestMapping(value = {"addUser"}, method = RequestMethod.GET)
    @ResponseBody
    public Boolean insertUser() throws Exception{
        User user = new User();
        user.setId(10);
        userServiceI.addUser(user);
        return true;
    }

Service

Service Interface

public interface UserServiceI {
    void addUser(User user);
}

Service Implementation class

@Service
public class UserService implements UserServiceI {

    @Autowired
    public UserDao userDao;

    @Autowired
    PersonService personService;

    @Override
    @Transactional(propagation= Propagation.REQUIRED,rollbackFor=Exception.class)
    public void addUser(User user){
        User user1 = userDao.saveAndFlush(user);
        System.out.println(1/0);
    }
}

Dao

public interface UserDao extends JpaRepository<User,Integer> {
}

My @Transactional method loads my implementation class Service, which writes an error-prone 1/0. I expect the transaction to roll back after the error, but it doesn't.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
John Ziv
  • 35
  • 6
  • 2
    Do you have the `@EnableTransactionManagement` in your configuration? If not the `@Transactional` doesn't do anything. – M. Deinum Feb 12 '19 at 09:08
  • can you paste the code of userdao class saveandflush method – vinay chhabra Feb 12 '19 at 09:21
  • @M.Deinum : thats simply wrong, transactions are enabled by default if you're using spring data _(which is what almost all people do)_ : https://stackoverflow.com/a/40724843/351861 – specializt Feb 12 '19 at 09:39
  • No they aren't. They are only enabled for the individual repository methods. Not for other methods. Hence the `@Transactional` even when using Spring Data is useless. – M. Deinum Feb 12 '19 at 09:43
  • you clearly didnt understand what i wrote. Maybe reading it again might help. Hint : the key information is hidden between the words "if" and "which". Your "other methods" are not spring data. Rolling up your own persistence layer is not spring data. Business methods usually are not spring data. – specializt Feb 12 '19 at 09:48
  • @M.Deinum:my project it's a non springboot project. and xml configuration file (where is declared your component-scan) the annotation-driven tag.If I hadn't written it, I would have missed NullPointerException when I used this service. – John Ziv Feb 12 '19 at 09:52
  • @vinay chhabra:the saveandflush method is method of springdatajpa。if you use the springdatajpa you will Understand。 – John Ziv Feb 12 '19 at 09:56
  • @钟光喜 : Is `UserDao` annotated with `@Repository`? – specializt Feb 12 '19 at 09:57
  • If you use xml you need `` else it won't work. If you are using XML then make sure you aren't scanning for the same components twice (both in the `ContextLoaderListener` and `DispatcherServlet`. If you'r transactions don't work (and they don't) then your tx setup is wrong/missing/borked. Regardless of the fact that Spring Data JPA is transactional by default, as that only applies to the `saveAndFlush` method, after that the tx has committed and nothing can be rolled back. – M. Deinum Feb 12 '19 at 10:30
  • Oh, I solved it because I omitted in applicationContext.xml. I only wrote in spring-mvc.xml. I always thought that I only need to write this in one of them. Until I saw this article https://labreeze.iteye.com/blog/2359957. I am too happy and negligent. Thank you @ M. Deinum for saying whether to scan repeatedly, which inspired me. – John Ziv Feb 12 '19 at 12:47

3 Answers3

2

Adding @Repository in your UserDao can be a possible fix of that error.
Not sure but it can work.

iamrajshah
  • 963
  • 1
  • 11
  • 23
0

Oh, I solved it because I omitted in applicationContext.xml. I only wrote in spring-mvc.xml. I always thought that I only need to write this in one of them. Until I saw this article labreeze.iteye.com/blog/2359957. I am too happy and negligent.

John Ziv
  • 35
  • 6
-1

if you are in a springboot project context you have to add @EnableTransactionManagement in your configuration class

if it's a non springboot project, add in your xml configuration file (where is declared your component-scan) the annotation-driven tag

sam3131
  • 357
  • 1
  • 9
  • wrong. Spring data has transaction management enabled by default : https://stackoverflow.com/a/40724843/351861 – specializt Feb 12 '19 at 09:41
  • my project it's a non springboot project. and xml configuration file (where is declared your component-scan) the annotation-driven tag.If I hadn't written it, I would have missed NullPointerException when I used this service – John Ziv Feb 12 '19 at 09:58
  • apparently, spring does not need the annotation to successfully create a valid repository out of the interface - i guess they changed this requirement some time ago : https://github.com/spring-projects/spring-data-examples/blob/master/jpa/jpa21/src/main/java/example/springdata/jpa/storedprocedures/UserRepository.java – specializt Feb 12 '19 at 10:08
  • Oh, I solved it because I omitted in applicationContext.xml. I only wrote in spring-mvc.xml. I always thought that I only need to write this in one of them. Until I saw this article https://labreeze.iteye.com/blog/2359957. I am too happy and negligent. Thank you @ M. Deinum for saying whether to scan repeatedly, which inspired me. – John Ziv Feb 12 '19 at 12:48
  • The answer is correct, but I didn't understand him at first. – John Ziv Feb 12 '19 at 12:48