I have a problem where I do have @Transactional
annotation in my service layer, but also repository layer. I fetch an entity and perform an partial update, then fetch all entities to perform some operation based on that updated field. Unfortunately the field has the old value. How can I solve this problem?
I make it work, when I deleted the @Transactional
annotation from the service layer, but it's needed there.
Also does it make sense to mark the whole repository as transactional, or only the UPDATE methods?
- Repository
@Repository
@Transactional
interface ExampleRepository extends JpaRepository<Ex, Long> {
@Modifying
@Query("UPDATE ExampleEntity e SET e.name = :name WHERE e.id IN (:ids)")
int updateName(@Param("name") String name, @Param("ids") Collection<Long> ids);
}
- Service
@Service
class ExampleService {
private final ExampleRepository exampleRepository;
ExampleService(final ExampleRepository exampleRepository) {
this.exampleRepository = exampleRepository;
}
@Transactional
public void updateName(Long id) {
exampleRepository.findById(id).ifPresent(e -> {
int updated = exampleRepository.updateName("NewName", List.of(e.getId()));
if(updated > 0) {
System.out.println("Updated"); // this is executed as updated is > 0
}
exampleRepository.findAll(); // returns entity with the old name
});
}
}