I have a list of ~10 000 objects.
I am trying to call an mysql update query (procedure) and then to get the updated objects inside same transaction. Can this be achieved ?
When I call a delete statement flush(), hibernate retrieves me correct objects (deleted objects are missing) But when I try update statement flush(), hibernate retrieves me the initial unchanged objects.
@Transactional
void test() {
//...
em.createQuery("delete from StorefrontProduct sp where sp in (:storefrontProducts)")
.setParameter("storefrontProducts", storefrontProductsToDelete)
.executeUpdate();
// example
em.createQuery("update StorefrontProduct sp set sp.orderIndex=0 where sp.id=90")
.executeUpdate();
em.flush();
//Simple JPA query
List<StorefrontProduct> result = repository.findAllByPreviousOrderIndexIsNotNull();
//additional code....
}
After running the code from above and putting a breakpoint after findAll call, provided objects from 1-st query were deleted and flushed, but the update query was not flushed.
CodePudding user response:
That is known counterintuitive behaviour of Hibernate.
First of all, em.flush()
call might be superfluous if flush mode set to AUTO
(in that case Hibernate automatically synchronises persistence context
(session-level cache) with underlying database prior executing update/delete queries).
Delete and successive Select case:
- you issues
delete
thenselect
, sinceselect
does not see deleted records anymore you do not see deleted records in resultset, however if you callfindById
you may find deleted records.
Update and successive Select case:
- you issues
update
thenselect
, when processing resultset Hibernate sees both records stored in database and records stored inpersistence context
and it assumes thatpersistence context
is a source of truth, that is the reason why you see "stale" data.
There are following options to mitigate that counterintuitive behaviour:
- do not perform direct updates, use "slow"
find/save
API instead - either
detach
orrefresh
stale entities after direct update,em.clear()
may also help, however it completely cleans uppersistence context
, which might be undesirable