Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data Rest transaction boundaries

I've been implementing some business logic/validation with the Spring Data Rest and JPA repositories using repository validators as described in:

http://docs.spring.io/spring-data/rest/docs/current/reference/html/#events.

After digging deeper into the SDR code I noticed that the validators (or more generally, repository listeners) are not invoked within a transaction.

From the source code of org.springframework.data.rest.webmvc.RepositoryEntityController:

private ResponseEntity<ResourceSupport> createAndReturn(Object domainObject, RepositoryInvoker invoker,
            PersistentEntityResourceAssembler assembler, boolean returnBody) {
        // validation logic is implemented in the listener, no transaction yet
        publisher.publishEvent(new BeforeCreateEvent(domainObject));
        // invoker calls repository, which is wrapped in the transactional proxy, 
        // only then transaction begins
        Object savedObject = invoker.invokeSave(domainObject);
        publisher.publishEvent(new AfterCreateEvent(savedObject));

        PersistentEntityResource resource = returnBody ? assembler.toFullResource(savedObject) : null;

        HttpHeaders headers = prepareHeaders(resource);
        addLocationHeader(headers, assembler, savedObject);

        return ControllerUtils.toResponseEntity(HttpStatus.CREATED, headers, resource);
}

As seen in the code, the listeners are not called within a transaction, which could lead to eventual data consistency issues.

Am I missing something? Or the framework simply sets the transactional boundary incorrectly?

like image 596
David Siro Avatar asked Dec 07 '25 06:12

David Siro


1 Answers

In spring data rest the repository method would run its own transaction. I also think that this is problematic in some cases. At least the event handler should be run in the same transaction as the repository method.

There was a similar question here: Handle spring-data-rest application events within the transaction

Especially this answer provides a workaround that allows you to wrap the whole RepositoryEntityController method in a transaction - I think this is what you need most of the time:

https://stackoverflow.com/a/30713264/5371736

like image 110
Mathias Dpunkt Avatar answered Dec 09 '25 19:12

Mathias Dpunkt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!