Как удалить сущности в отношениях «многие ко многим» в Hibernate - PullRequest
3 голосов
/ 23 сентября 2019

У меня есть два класса сущностей: учетная запись и роль.Они сопоставлены с отношением многих ко многим.Я хочу удалить одну учетную запись из базы данных.Код ниже работает для меня, однако, я считаю, что есть лучший подход.

Мой Account.class:

public class Account {

    //some code

    @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    @JoinTable(name = "account_role",
            joinColumns = {@JoinColumn(name = "account_id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id")})
    private Set<Role> roles = new HashSet<>();

}

Мой Role.class:

public class Role {

    //some code

    @EqualsAndHashCode.Exclude
    @ManyToMany(mappedBy = "roles", fetch = FetchType.EAGER,
             cascade = {CascadeType.MERGE , CascadeType.PERSIST/*, CascadeType.DETACH, CascadeType.REFRESH*/})
    private Set<Account> accounts = new HashSet<>();
}

Это мое отображение в PostgreSQL

Db map pic

TL; DR

Приведенный ниже код работает нормально, какой подход лучше?

@Override
public void deleteUserAndHisTokensById(Long accountId) {
    Account accountToBeDelete = accountRepository.findDistinctById(accountId);
    accountToBeDelete.getRoles()
            .forEach(role -> {
                Set<Account> updatedAccounts = role.getAccounts()
                        .stream()
                        .filter(account -> !account.equals(accountToBeDelete))
                        .collect(Collectors.toSet());
                role.setAccounts(updatedAccounts);
                roleRepository.save(role);
            });

        accountToBeDelete.setRoles(null);
        accountRepository.deleteById(accountId);
    }

1 Ответ

2 голосов
/ 23 сентября 2019

Если вы добавите CascadeType.REMOVE, как упомянуто @JonathanJohx.Вы сможете удалить его следующим образом:

accountRepository.deleteById();

Более того, если вы хотите удалить роли из учетных записей, добавьте CascadeType.REMOVE к другой стороне отношений, чтобы вы могли сделать это:

Role role = roleRepository.findById(10);
Account account = accountRepository.findById(11);
account.getRoles().remove(role);
...