spring-projects / spring-data-jpa

Simplifies the development of creating a JPA-based data access layer.
https://spring.io/projects/spring-data-jpa/
Apache License 2.0
2.93k stars 1.39k forks source link

Bug: Missing implicite entityManager.flush() before storedprocedure call and Spring-Data Repository #3434

Closed ere-one closed 2 months ago

ere-one commented 2 months ago

Relates to https://github.com/spring-projects/spring-data-jpa/issues/3433

Actually it is a bug in the Sppring Data JPA Repository. Because entityManager.flush() must be called implicitally by a vendor if FlushModeType.AUTO is used, see related JEE API Doc: https://docs.oracle.com/javaee%2F7%2Fapi%2F%2F/javax/persistence/FlushModeType.html

"... the persistence provider is responsible for ensuring that all updates to the state of all entities in the persistence context which could potentially affect the result of the query are visible to the processing of the query. ..."

In case of a Spring-Data JPA Repository methods annotated with @Query, the entityManager.flush() will be called implicitally before executing the query, so the query can use/see the changes made in the same transaction. In case of a Spring-Data JPA Repository methods annotated with @Procedure the entityManager.flush() will not be called implicitally, so the stored procedure, in which queries may be used, will not use/see changes made in the same transaction.

We use Spring-Boot 2.7.10

mp911de commented 2 months ago

The short answer: We cannot know when to call flush.

The longer variant: Spring Data JPA adopts naturally JPA patterns and therefore it does not want to enforce flushing on each operation to slow down your application. As we do not know the order in which you're calling repositories, updating entities and such, we cannot flush for you. That is something that you need to control from your application as only your application known the appropriate time for flushing.

If we would call flush every time someone calls a stored procedure, we would impose a lot of implicit traffic and we would change the application state in a potentially breaking way.

schauder commented 2 months ago

Actually it is a bug in the Sppring Data JPA Repository. Because entityManager.flush() must be called implicitally by a vendor if FlushModeType.AUTO is used

This is a non sequitur. Spring Data JPA is not a JPA implementation. Hibernate and Eclipse are.

ere-one commented 2 months ago

@mp911de Hmm, in case of JPA Repository using @Query (including 'nativeQuery') you some how knows it and triggers the flush(). Your above arguments are applieble to @Query as well. IMHO this should be the same with @Procedure.