JPA删除子级而不删除父级

时间:2020-07-08 20:50:16

标签: java spring-boot jpa spring-data-jpa

我正在使用Spring Boot 2.3.0。

我的一侧有ManyToOne关系,另一侧是OneToMany关系。一位父母可以带很多孩子,但是很多孩子可以带一位父母。我试图能够删除子项而不影响父项。对于父字段,我在子级上有nullable = false,因为我不想在parent_to_child表中以父级的意外空值结尾。我希望这样的事情得到执行并被抓住。

readerRepository.save(reader)对象(这是父对象)的TBRList中删除List<TBRList>项(这是孩子)中的一个Reader时,尝试删除子项时,我不断收到有关父项字段不能为null的错误。如果我在子对象的父字段中将nullable设置为false,则我的父项会消失。

我以为我知道这应该是如何工作的,但显然不是。

我有:

@Entity //parent
public class Reader implements Serializable {

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

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "reader", orphanRemoval = true)
    Set<TBRList> tbrLists = new HashSet<>();

    //other fields, getters, setters, etc.
}



@Entity(name = "tbr") //child
public class TBRList implements Serializable {
    
    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @JsonIgnore
    @ManyToOne
    @JoinColumn(name = "reader_id", nullable = false)
    private Reader reader;

    //other fields, getters, setters, etc
}

在下面的代码段中,readerRepository.save(reader)发生了org.hibernate.PropertyValueException: not-null property references a null or transient value : com.me.project.entity.TBRList.reader异常。

if (reader.hasTBRList(tbrListName)) {
    Iterator<TBRList> it = reader.getTbrLists().iterator();
    while (it.hasNext()) {
        TBRList tbrList = it.next();
        if (tbrList.getName().equals(tbrListName)) {
            it.remove();
            readerRepository.save(reader);
            break;
        }
    }
}

我也尝试在reader中将TBRList设置为null,并通过deletetbrListRepository设置为null,但是发生了同样的事情。实际上,我已经尝试了太多的事情来记住所有这些事情(经过数小时的搜索和尝试,我尝试提出问题作为最后的结果)。

尝试建立父子关系时,我不想要做什么,我不希望Child.parent为null,并且希望能够从父级中删除子级而又不删除父级中的父级。过程吗?

1 个答案:

答案 0 :(得分:0)

我创建了相同的类,并根据需要执行以下结果:

@Entity(name = "tbr")
@Data
public class TBRList {

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

    @Column(nullable = false)
    private String name;

    @JsonIgnore
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "reader_id", nullable = false)
    private Reader reader;

}


@Entity
@Data
public class Reader {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "reader", orphanRemoval = true)
    Collection<TBRList> tbrLists ;


}