Цель состоит в том, чтобы проверить и удалить карту пользователя при ее удалении, при условии, что она больше не используется. Это формат удаления пользователя:
@Transactional
public void deleteUserById(long userId) {
User user = userRepository.findById(userId);
if (user == null) {
throw new IllegalArgumentException("User with id " + userId + " not found");
}
userRepository.deleteById(userId);
}
В этом формате пользователь удаляется только при выполнении условия «если», то есть когда карта принадлежит исключительно удаляемому пользователю. Однако если карта принадлежит более чем одному пользователю, код выполняется корректно, но пользователь не удаляется из базы данных. В чем может быть причина этого?
@Transactional
public void deleteUserById(long userId) {
User user = userRepository.findById(userId);
if (user == null) {
throw new IllegalArgumentException("User with id " + userId + " not found");
}
if (userBankCardService.checkBankCardUsers(user.getUserBankCard().getCardNumber()) == 1) {
userBankCardService.deleteBankCard(user.getUserBankCard().getCardNumber());
}
userRepository.deleteById(userId);
}
Если это важно, вот мои сущности.
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@ToString(exclude = "users")
@Table(name = "users_bank_cards")
public class UserBankCard {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "card_number")
private long cardNumber;
@Column(name = "cvv")
private short cvv;
@Column(name = "card_expiration_date")
private String cardExpirationDate;
@OneToMany(mappedBy = "userBankCard", cascade = CascadeType.ALL)
@JsonIgnore
private List<User> users = new ArrayList<>();
}
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@ToString(exclude = {"subscription"})
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "phone_number")
private long phoneNumber;
@Column(name = "password")
private String password;
@Column(name = "auto_renew")
@Enumerated(EnumType.STRING)
private AutoRenewStatus autoRenew;
@Column(name = "end_time")
private LocalDateTime endTime;
@Column(name = "email")
private String email;
@ManyToOne
@JoinColumn(name = "bank_card_id")
private UserBankCard userBankCard;
@ManyToOne
@JoinColumn(name = "subscription_id")
private Subscription subscription;
}
Как удалить пользователя, если карту удалять не обязательно?
Полностью согласен с @g00se. Создайте новый столбец в таблице БД, указывающий, что он заархивирован в логическом состоянии. Это гарантирует, что что-то будет удалено по ошибке.
@djmonki, конечно, означает, что это гарантирует, что что-то НЕ будет удалено по ошибке.
Или вместо BOOLEAN используйте столбец типа, подобного стандартному типу SQL TIMESTAMP WITH TIME ZONE, чтобы указать, была ли и когда строка «удалена» (инактивирована).
@g00se - спасибо, что заметили ошибку в моем комментарии




вероятно, есть внешний ключ. попробуйте удалить пользователя самостоятельно прямо в базе данных и проверьте, нет ли ошибок. В моем случае спящий режим не выдаст никаких исключений по этому поводу.
Не обратил внимания на кеширование Hibernate. После удаления пользователя из списка пользователей кредитных карт, пользователь также удаляется из базы данных.
Если нет юридического требования, всегда лучше пометить что-то как неактивное, чем удалять. Данные – золото