@Modifying does not flush session when put over method defined in custom implementation [DATAJPA-1445]
Сергей Цыпанов 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
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
Сергей Цыпанов 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
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
@Modifyingthat 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
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
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