Spring data - @Modifying(clearAutomatically = true , flushAutomatically = true) causing another entity not to be updated

Viewed 71

We have a repository that have the following update:

@Query(value="UPDATE Brand set name=?1 where id=?2")
@Modifying(clearAutomatically = true , flushAutomatically = true)
int updateBrandName(String name, Long brandId);

We are experiencing a weird behavior on the following case:

@Transactional
public void test() {
    Brand b = brandRepository.findById(1);
    Settings s = settingsRepository.findById(2);        

    brandRepository.updateBrandName("some new name", 1);   // WILL BE PERSISTED
    s.setModifiedBy(null);  //  WONT BE PERSISTED
}

Another use case that works differently:

@Transactional
public void test() {
    Brand b = brandRepository.findById(1);

    brandRepository.updateBrandName("some new name", 1);   // WILL BE PERSISTED
    b.setSomeOtherField(null);  //  WILL BE PERSISTED
}

Removing the (clearAutomatically = true) solves the problem (everything is peristed)

Why the Settings entity is not persisted while the original Brand entity does when the clearAutomatically = true?

If we do need the clear automatically = true, how can we do it properly?

1 Answers

This works as designed. As the Javadoc suggests, clearAutomatically triggers persistence context clearance, i.e. calls EntityManager.clear(). The Javadoc of that clearly states:

Clear the persistence context, causing all managed entities to become detached. Changes made to entities that have not been flushed to the database will not be persisted.

That's why your modification of s does not get persisted. I guess an explicit call settingsRepository.save(s) should do the trick as it merges the now detached instance to the persistence context again.

Related