0

Here is the behavior I wish to achieve:

@Transactional(rollbackFor = NullPointerException.class)
    @PostMapping(consumes = {"application/json"})
    public Employee createEmployee(@Valid @RequestBody Employee employee) {
        Optional<Department> departmentOptional = departmentRepository.findById(employee.getDeptId());
        EmployeeAggregate employeeAggregate = employeeAggregateRepository.findAll().get(0);
        employeeAggregate.setTotalEmployeeCount(employeeAggregate.getTotalEmployeeCount()+1);
        employeeAggregateRepository.save(employeeAggregate); <--This line should be rolled back when exception is thrown.
        if(departmentOptional.isPresent()) {
            Department department = departmentOptional.get();
            return employeeRepository.save(employee);
        }
        else{
            throw new NullPointerException();
        }
    }

There are two documents, Employees, and EmployeeAggregate. I want to be able to rollback the employee count stored in EmployeeAggregate if I am unable to create an employee in Employees document.

Here is my mongo config file:

@Configuration
public class MongoConfig {

    @Bean
    @Autowired
    @ConditionalOnExpression("'${mongo.transactions}'=='enabled'")
    MongoTransactionManager mongoTransactionManager(MongoDbFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }

    public @Bean MongoClient mongoClient() {
        return new MongoClient("localhost");
    }

    public @Bean
    MongoTemplate mongoTemplate() {
        return new MongoTemplate(mongoClient(), "EmployeeDatabase");
    }
}

Currently, no rollback takes place if Employee creation fails. The count gets updated by one irrespective of successful employee creation or not. An explanation of multidocument transactions in spring boot would be appreciated, since the documentation is a bit confusing.

NobleSiks
  • 329
  • 2
  • 4
  • 17
  • _"An explanation of multidocument transactions in spring boot would be appreciated, since the documentation is a bit confusing"_: Please post the link to the referred documentation. – prasad_ Jan 20 '20 at 09:37
  • 1. If you move the employeeAggregateRepository.save(employeeAggregate); inside the if condition , the save for both EmployeeAggregate and Employee will happen together. 2. Are you sure NPE is thrown when employee is not saved ? . – R.G Jan 20 '20 at 09:46
  • [This](https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.transactions) is the link. I am unable to understand the code snippets. I am new to spring boot, so am not very familiar with project structures, so to me there are a quite a few unexplained objects and variable. – NobleSiks Jan 20 '20 at 09:47
  • @R.G Yeah, I get that it would solve the problem, but I intentionally put it outside, since I wanted to see the rollback in action. But no rollback is taking place. I am not sure what to do here. – NobleSiks Jan 20 '20 at 09:51
  • two things to make sure first.1. remove this to create the bean unconditionally @ConditionalOnExpression("'${mongo.transactions}'=='enabled'") 2. Make sure NPE is thrown – R.G Jan 20 '20 at 09:57
  • @R.G so, when I removed the @ ConditionalOnExpression, I get this error when NPE is thrown: "Sessions are not supported by the MongoDB cluster to which this client is connected". What to do about this? – NobleSiks Jan 20 '20 at 10:19
  • Does this help ? https://stackoverflow.com/questions/50255195/how-to-configure-a-mongodb-cluster-which-supports-sessions – R.G Jan 20 '20 at 10:21
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/206275/discussion-between-noblesiks-and-r-g). – NobleSiks Jan 20 '20 at 11:05
  • @NobleSiks, did you find any solution for this? I'm working on a similar scenario and the outcome is same. – prince Sep 15 '22 at 07:55

0 Answers0