Скрипт записи данных в поле таблицы
Существует таблица Users и таблица Balance. Связанные связью @OneToMany: один пользователь - много балансов.
Пример структуры в ответе метода

Что нужно? Написать скрипт-логику по следующему алгоритму:
- Метод получает список пользователей из БД из таблицы
Users - Пробегаемся по списку и получаем балансы пользователей
Balance - Находим записи у которых поле
tax = null - Записываем для таких записей поле
tax = 0.20 - Значения где
tax != nullпропускаем - Завершение
Часть логики которую написал но не могу закончить. Как сделать проверку по полю tax и записать данные для записей tax = null корректно? Достаточно будет примера.
public class JobUserBalance {
private final UserService userService;
private final UserRepo userRepo;
private final BalanceRepo balanceRepo;
private final BalanceService balanceService;
public JobUserBalance(UserService userService, UserRepo userRepo, BalanceRepo balanceRepo, BalanceService balanceService) {
this.userService = userService;
this.userRepo = userRepo;
this.balanceRepo = balanceRepo;
this.balanceService = balanceService;
}
public void setTax() {
Iterable<Users> users = userRepo.findAll(); // получаем список пользователей
users.forEach(users1 -> users1.getBalance().forEach(balance -> balance.getTax())); // пробегаемся по сущности Users получаем балансы, далее поле tax
// если значение tax у пользователя = null, то для каждой записи где null для каждого пользователя проставляем значение 0.20
// записи где tax != null пропускаем
}
}
таблица User
package com.example.rabbit_new2.entity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.List;
@Entity
@Data
@Table(name = "users_balance")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "name")
private String name;
@NotNull
@Column(name = "address")
private String address;
@NotNull
@Column(name = "code")
private Integer code;
@Column(insertable = true, updatable = false)
private LocalDateTime dateCreated;
private LocalDateTime dateModified;
@PrePersist
void onCreate() {
this.setDateCreated(LocalDateTime.now());
this.setDateModified(LocalDateTime.now());
}
@PreUpdate
void onUpdate() {
this.setDateModified(LocalDateTime.now());
}
@OneToMany
@JoinTable(
name = "balance_calc",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "id")
)
private List<Balance> balance;
@OneToOne
@JoinTable(
name = "data_users",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "id")
)
private DataUser dataUser;
}
таблица Balance
package com.example.rabbit_new2.entity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "balance_calc")
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Balance {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "name")
private String name;
@NotNull
@Column(name = "sum")
private Double sum;
@Column(name = "tax")
private Double tax;
@Column(name = "result")
private Double result;
@Column(name = "user_id")
private Long userId;
@Column(insertable = true, updatable = false)
private LocalDateTime dateCreated;
private LocalDateTime dateModified;
@PrePersist
void onCreate() {
this.setDateCreated(LocalDateTime.now());
this.setDateModified(LocalDateTime.now());
}
@PreUpdate
void onUpdate() {
this.setDateModified(LocalDateTime.now());
}
}
Ответы (1 шт):
Собственно, вот:
for (User user : users) { // проход по списку пользователей
for (Balance balance : user.getBalances()) { // проход по списку балансов очередного пользователя
if (balance.getTax() == null) { // если поле tax очередного баланса содержит значение null
balance.setTax(0.2); // устанавливаем его в 0.2
balanceService.save(balance); // сохраняем результат, чтобы он был записан в БД
}
}
}
Если делать при помощи forEach(), как вы пытались, то может получиться так:
users.forEach(user -> user.getBalance().forEach(balance -> {
if (balance.getTax() == null) {
balance.setTax(0.2);
balanceService.save(balance);
}
}));
Скорее всего, код можно ещё как-нибудь улучшить и сократить.
Помимо этого, хочу обратить внимание на странность в приведённом вами классе. Вы внедряете в него и репозитории, и соответствующие им сервисы. Так быть не должно. В идеале репозиторий внедряется только в одноимённый с ним сервис, а вся дальнейшая работа с сущностями в приложении осуществляется через сервисы.
Соответственно, вам должно быть достаточно внедрения userService и balanceService. Все действия, которые вы планируете делать над сущностями, должны быть покрыты этими сервисами.
И это уже не говоря о том, что решению всей этой задачи и вовсе не нужно находиться в отдельном классе. Это вполне себе работа какого-нибудь из двух упомянутых выше сервисов. Скорее даже userService-а.
Задача представляет собой смену null-поля tax балансов пользователей. Значит, вполне логично в сервисе юзеров создать метод changeNullTaxBalances(), в который и поместить приведённый в начале ответа код.