In my recent project I faced a scenario where I need to rollback database operation when error happen in nested method. Earlier I worked with @Transactional on single method. That time it worked fine. But in current scenario I have dependency on another method. So I need to rollback when error happen is nested method. I want to rollback in this method
@Transactional
@Override
public String updateCustomOfficeHour(OfficeHour officeHour) {
if (officeHour.getId() == null || officeHourRepository.getFirstById(officeHour.getId()) == null)
throw new EntityNotFoundException("No Office-Hour found with this id");
OfficeHour temp = officeHourRepository.getFirstById(officeHour.getId());
List<OfficeHour> officeHours = officeHourRepository.findByFromDateAndToDate(temp.getFromDate(), temp.getToDate());
List<OfficeHour> tempList = new ArrayList<>();
for (OfficeHour officeHourObj : officeHours) {
officeHourObj.setDeleted(true);
tempList.add(officeHourObj);
}
officeHourRepository.saveAll(tempList);
this.createCustomOfficeHour(officeHour);
return "Updated Custom-Office-Hour";
}
Here I have a database operation in line officeHourRepository.saveAll(tempList);
I need to rollback when error occur in method this.createCustomOfficeHour(officeHour);. This method is
@Transactional
@Override
public String createCustomOfficeHour(OfficeHour officeHour) {
if (officeHour.getFromDate() == null || officeHour.getToDate() == null
|| officeHour.getFirstOutTime() == null || officeHour.getLastInTime() == null
|| officeHour.getInTime() == null || officeHour.getOutTime() == null)
throw new EntityNotFoundException("Null value received for OfficeHour fields!");
if (officeHour.getToDate().compareTo(officeHour.getFromDate()) < 0)
throw new EntityNotFoundException("FromDate is Getter than ToDate");
if (officeHourRepository.isFromDateExist(officeHour.getFromDate()).longValue() > 0
|| officeHourRepository.isToDateExist(officeHour.getToDate()).longValue() > 0) {
throw new EntityNotFoundException("FromDate/ToDate is already assigned");
}
if (officeHourRepository.isDateExistsBetweenFromAndToDate(officeHour.getFromDate(), officeHour.getToDate()).longValue() > 0)
throw new EntityNotFoundException("Office Hour Already Assigned In This Range");
for (int i = 1; i <= count; i++) {
........
........
........
officeHourRepository.save(obj);
}
return "Custom Office-Hour Created";
}
And this is my Exception class
public class EntityNotFoundException extends RuntimeException {
public EntityNotFoundException(String message) {
super(message);
}
}
I have also added spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect in application.properties
Any help will be appreciated.
Your
EntityNotFoundExceptionis a non-checked exception and following the spring docs:the transaction should be rolled back by default.
This is because
updateCustomOfficeHourandcreateCustomOfficeHourare processed under same transaction (there is no override of propagation here so the default REQUIRED is used).You could add an explicit rollback for your exception on the
updateCustomOfficeHourmethod but that should be redundant anyway: