spring-data-jpa icon indicating copy to clipboard operation
spring-data-jpa copied to clipboard

@Modifying does not flush session when put over method defined in custom implementation [DATAJPA-1445]

Open spring-projects-issues opened this issue 7 years ago • 6 comments

Сергей Цыпанов opened DATAJPA-1445 and commented

Consider the method

@Override
@Modifying(flushAutomatically = true)
public void deleteContractDataBySnapshotId(Long snapshotId) {
  //getSession().flush();
  String query = "delete from table sn where sn.smth = true ";
  getSession().createNativeQuery(query)
    .addSynchronizedQuerySpace("") //keep 2nd level cache
    .executeUpdate();
 }

This code doen't flush session which is why we have to uncomment

getSession().flush()

I think this behaviour is not correct, otherwise this must be specified in javadoc


No further details from DATAJPA-1445

spring-projects-issues avatar Oct 19 '18 07:10 spring-projects-issues

Oliver Drotbohm commented

@Modifying is only supported on actual query methods, not on manually implemented ones. I also think it doesn't make sense to enable that for manually defined methods as you have access to all the infrastructure you need and a getSession().flush() is much more explicit than an annotation above the method

spring-projects-issues avatar Oct 19 '18 07:10 spring-projects-issues

Сергей Цыпанов commented

Oliver Drotbohm there are some problems with explicit getSession().flush():

  • in several years no one would remember what was the purpose of the manual flush in RepoImpl methods of the project
  • there is always a change that some native requests would remain without getSession().flush()
  • if the approach will be somehow changed then they have to rework the code in lots of places

I think we should either explititly specify in javadoc of @Modifying that it's only for methods declared in repository interfaces, or make it applicable for implementations

spring-projects-issues avatar Oct 19 '18 10:10 spring-projects-issues

Oliver Drotbohm commented

in several years no one would remember what was the purpose of the manual flush in RepoImpl methods of the project How is that different from not knowing about the purpose of the annotation?

There is always a change that some native requests would remain without getSession().flush().

Just as there would if the annotation was missing. What's the difference?

if the approach will be somehow changed then they have to rework the code in lots of places

If Hibernate changes the way Session.flush() works, that's certainly true. But that's a tautology and not something Spring Data can fix.

I think we should either explititly specify in javadoc of @Modifying that it's only for methods declared in repository interfaces, or make it applicable for implementations.

We can certainly be more explicit about the usage model in the JavaDoc. We could even inspect the custom methods to make sure they don't contain any annotations that are only inteded to be used on actual query methods

spring-projects-issues avatar Oct 19 '18 10:10 spring-projects-issues

Сергей Цыпанов commented

Why cannot we make @Modifying applicable for methods declared in RepoImpl?

spring-projects-issues avatar Oct 19 '18 10:10 spring-projects-issues

Oliver Drotbohm commented

Because it's evaluation is tied to the code that's executing query methods and a custom method implementation is not a query method. Also – as indicated before – the pure fact that you implement a query method yourself is a signal to Spring Data that you want to take care of the query execution yourself. Starting to mix the query method execution functionality with custom implementation methods blurs the line and adds complexity.

Another issues is that the way you indicate you' like to use Session.flush() is not even the way @Modifying(flushAutomatically = true) is applied. As the JavaDoc clearly suggests, the flag controls whether the persistence context, (i.e. EntityManager – not even the Session) is supposed to be flushed after the query has been executed. It's not flushed before the query execution. Also, with a custom implementation method it's not even clear what "the query" actually is as you can literally do anything inside the method.

To wrap things up here: @Modifying is an annotation that only makes sense on Spring Data query methods (derived or manually) and not on custom implementations

spring-projects-issues avatar Oct 19 '18 10:10 spring-projects-issues

Oliver Drotbohm commented

I am sorry, I was looking at an ancient version of the annotation that only had the clearAutomatically attribute which executed after the query execution. The rest of the argument certainly stays the same

spring-projects-issues avatar Oct 19 '18 10:10 spring-projects-issues