4

I do data processing that I can't or don't want to do on the database level, I use streams:

I need to filter users according to some algorithms and then set the name for the users found to database.

    userRepository
    .findAll()
    .stream()
    .filter(isFourierTransform())
    .forEach(i ->i.setName("Fourier");

Unfortunately, the above code does not save anything to database.

Below the working code

List<User>user=userRepository
.findAll()
.stream()
.filter(isFourierTransform())
.collect(Collectors.toList());

for(User user:u)
{
    user.setName("")
}


userRepository.save(user);

how to make the first example work?

Kamil Nękanowicz
  • 6,254
  • 7
  • 34
  • 51
  • Running that code in a `@Transactional` service method should make it work. – M. Deinum Feb 06 '18 at 09:34
  • The second variant is fine (besides the fact that you can’t have two variables of the same name). You can replace the loop with `user.forEach(u -> u.setName("Fourier"));` if that makes you feel better. – Holger Feb 06 '18 at 15:48

1 Answers1

3
userRepository
  .findAll()
  .stream()
  .filter(isFourierTransform())
  .map(i -> { i.setName("Fourier"); return i;}
  .forEach(userRepository::save)
Eugene
  • 117,005
  • 15
  • 201
  • 306
  • what about collecting the result in a list and call the repo only once? Would not it be better in terms of performance? – gWombat Feb 06 '18 at 09:34
  • Using `map` for manipulating on object is not better than `peek`… – Holger Feb 06 '18 at 15:46
  • @Holger I always thought that it is somehow "safer", might be a false feeling here. But how would that be done otherwise? – Eugene Feb 06 '18 at 15:48
  • 1
    It’s not safer; there’s no guaranty about the processing order or which elements get processed in the case of a short-circuiting operation and it may get skipped entirely, e.g. when the terminal operation is `count()`, just like with `peek`. And it’s contradicting the intention of the operation, just like with `peek`. You can simply replace the last two operations with `.forEach(u -> { u.setName("Fourier"); userRepository.save(u); });` or even better, stay with the OP’s second variant which is already working and potentially more efficient (by using a single transfer for the entire list). – Holger Feb 06 '18 at 15:53