Способ удалить строку из таблицы ассоциации, когда класс удаляет ссылку на него? - PullRequest
0 голосов
/ 11 апреля 2019

У меня есть три класса, Пользователь и Продукт, и их класс связи Порядок.Я хотел иметь возможность добавлять и удалять строки в таблице сопоставлений, редактируя Set либо в User, либо в Product.Добавление работает, но когда я удаляю некоторые Заказы, например, из Пользователя, они сохраняются в БД.

Следуя этому примеру Я придумал этот код.

@Getter
@Setter
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Set<Order> orders;

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
        orders.forEach(order -> order.setUser(this));
    }
}

@Getter
@Setter
@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
    private Set<Order> orders;

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
        orders.forEach(order -> order.setProduct(this));
    }
}

И класс ассоциации:

@Getter
@Setter
@Entity
@NoArgsConstructor
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @ManyToOne
    @JoinColumn
    private Product product;

    @NotNull
    @ManyToOne
    @JoinColumn
    private User user;

    public Order(User user, Product product) {
        this.user = user;
        this.project = project;
    }

    @Override
    public boolean equals(Object o){
        if (this == o) return true;
        if (!(o instanceof Order)) return false;
        Engagement that = (Order) o;
        return Objects.equals(user.getUsername(), 
                           that.user.getUsername()) &&
               Objects.equals(product.getName(), 
                           that.product.getName());
    }

    @Override
    public int hashCode(){
        return Objects.hash(user.getUsername(), 
                           product.getName());
    }
}

в моем классе OrderService я добавляю и редактирую набор Orders следующим образом:

public addProductsToUser(User user, Set<Product> products){
    Set<Order> orders = products.stream().map(product -> new Order(user, product)).collect(Collectors.toSet());
    user.setOrders(orders);
    userRepository.save(user); //save from CrudRepository
}

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

1 Ответ

0 голосов
/ 11 апреля 2019

Я думаю, что вы ищете orphanRemoval = true.Это указывает, что объекты, которые отключены от родителя, будут удалены.

В вашем случае аннотация будет выглядеть примерно так:

@OneToMany(mappedBy = "user", orphanRemoval = true, cascade = CascadeType.ALL)
private Set<Order> orders;

Для получения дополнительной информации и разницы между этими двумясм. этот пост: В чем разница между каскадным и бесхозным удалением из БД?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...