从列表中删除子项时,也会删除父项

时间:2019-08-23 08:15:05

标签: mysql spring hibernate spring-boot jpa

我有两个类User和Task。当我从列表中删除一个孩子时,我只想删除该孩子,相反,它也删除了父孩子。我想保留父级(用户),但要从列表中删除子级(“任务列表”)。

用户类别:

@Entity
@AllArgsConstructor
@Getter
@Setter
@NoArgsConstructor
@Table(name = "users",
        uniqueConstraints = {
                @UniqueConstraint(name = "unq_email_users", columnNames = "email")
        })
public class User {

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

    @Column(name = "first_name", nullable = false)
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email", nullable = false)
    private String email;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "FK_users"))
    private List<Task> tasks = new ArrayList<>();

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

任务类:

@Entity
@Table(name = "tasks")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class Task {

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

    @Column(name = "title")
    private String title;

    @Column(name = "description")
    private String description;

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private User user;

    @Override
    public String toString() {
        return "Task{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", description='" + description + '\'' +
                '}';
    }
}

这是我用来从列表中删除子级的服务方法:

public User removeUserTask(Long userId, Long taskId) {
        Optional<User> userOptional = userRepository.findById(userId);
        if(!userOptional.isPresent()) {
            throw new NotFoundException("No User Found With Id - " + userId);
        }

        User user = userOptional.get();
        Task task1 = user.getTasks().stream().filter(task -> task.getId().equals(userId)).findFirst().orElse(null);
        if(task1==null) {
            throw new NotFoundException("No Task Found With Id - " + taskId);
        }
        user.getTasks().remove(task1);
        userRepository.save(user);
        return user;
    }

但令人惊讶的是,它也删除了父级。

我想做的是从表中删除仅任务,但是当我删除任务时,它也会删除父任务和其他任务。 orphanRemoval = true 不应只删除那些与用户无关的任务。

2 个答案:

答案 0 :(得分:0)

这是因为您告诉休眠状态通过使用cascade = CascadeType.ALL来级联更改。如果您不想删除父对象,则需要将其删除或提供一个包含CascageType以外的CascadeType.REMOVE的数组,例如:

@ManyToMany(cascade = {
    CascadeType.PERSIST,
    CascadeType.MERGE
})

答案 1 :(得分:0)

我已经弄清楚了,我在两个实体中都使用cascade = CascadeType.ALL,因此删除 Task 会自动删除 User ,我已更改

cascade = CascadType.All

@ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)

在Task实体上,并且工作正常。