Reputation: 65
I am using Spring JpaRepository for CRUD implementation in one of my App screens. As a part of that, I am developing a feature where user can save all Car entities or nothing (should roll back) into database. I am not sure how do I achieve this functionality using Spring Boot, Spring Rest, Spring Jpa.
Below is my source code.
@Repository
interface CarRepository extends JpaRepository<Car, Integer> { }
@Service
class CarService {
@Autowired
CarRepository repo;
@Transactional(rollbackFor=RuntimeException.class)
public List<Car> saveAllOrNone(List<Car> cars) {
for(Car car: cars) {
repo.save(car);
}
}
}
I am unable to figure out what wrong I am doing.
When I tested it using two different data among which 1 have invalid data, the other record is getting inserted into database instead of being rolled back.
In addition to this, I am getting an Exception like
UOWManager transaction processing failed:nested exception is com.ibm.wsspi.uow.UOWException: javax.transaction.RollbackException
Please help me out. Thank you.
Upvotes: 2
Views: 4158
Reputation: 65
Even though its late, I would like to post the answer because someone would find this useful. I fixed the error by implementing a JPA Transaction Manager in my spring boot application using the resource here
Upvotes: 2
Reputation: 19050
Seems the @Transactional is not working for you. I could understand that there is some configuration in your application that could be the responsible to not create the DataSourceTransactionManager
. As explained here, this should be automatically:
Spring Boot will detect spring-jdbc on the classpath and h2 and will create a DataSource and a JdbcTemplate for you automatically. Because such infrastructure is now available and you have no dedicated configuration, a DataSourceTransactionManager will also be created for you: this is the component that intercepts the @Transactional annotated method
So I see two alternatives to resolve your problem.
The first is use the save
method from Spring Repository that could accept your car list:
repo.save(cars);
This will work because the Spring has an internal @Transactional for the repository methods.
The another alternative is add together with your @SpringBootApplication
the annotation @EnableTransactionManagement
, enabling manually what Spring should do for you.
More details here.
Upvotes: 0