I am trying to process a record within a @Transactional
annotated method. There are some dependencies from other methods that must be taken care before processing some other secondary (but necessary) business logic. The main record seems to be saved with no problem inside the transaction, but when I try to clean some data by using another service, it throws a JpaEntityNotFoundException
.
I used Propagation.REQUIRES_NEW
in the method that causes the issue, but with no success. Does anyone have an idea about what I am missing or doing wrong? I must not commit the main record before doing the rest of the transactional operations.
The exception that I am getting is: org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find com.myproject.repository.entity.Book with id 5851445; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.myproject.repository.entity.Book with id 5851445...............
Here is an example that shows somehow my issue:
ServiceA class
@Service
public class ServiceA {
public void nonTransactionalMethodA(Book book) {
//..... Any independent logic from ServiceB
updateAuthor(book);
nonTransactionalMethodB();
}
public void nonTransactionalMethodB() {
//post process logic ......
}
}
ServiceB Class
@Service
public class ServiceB {
@Autowired
private BookRepository bookRepository;
@Autowired
private OfferRepository offerRepository;
@Transactional
private void updateAuthor(Author author) {
Book book = new Book(1);
book.setAuthor(author);
bookRepository.save(book);
removeUnavailableOffers(book);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void removeUnavailableOffers (Book book) {
/*throwing org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find com.myproject.repository.entity.Book with id 5851445; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.myproject.repository.entity.Book with id 5851445............*/
offerRepository.deleteByBookIdIsNullAndBookAuthorIdNot(book.authorId);
}
}
Any thought on this will be greatly appreciated.
Propagation.REQUIRES_NEW
? It's for the partial rollback, and not all databases support it. If you have several transactions your "other" service should be annotated with@Transactional
and called from another@Transactional
method that calls both services if it wants to see the changes made in transaction. P.S. and @Modus is right about private methods,@Transactional
is never expected to do anything with private methods – Boris Treukhov