简体   繁体   中英

JPA delete child without deleting parent

I am using Spring Boot 2.3.0.

I have a ManyToOne relationship on one side and a OneToMany relationship on the other side. One parent to many children, but many children to one parent. I am trying to be able to delete children without affecting the parent. I have nullable = false on the child side for the parent field because I don't want to end up with accidental nulls for parent in the parent_to_child table. I want things like that to be enforced and get caught.

When I do readerRepository.save(reader) after removing one of the TBRList items (this is the child) from the List<TBRList> in the Reader object (this is the parent), I keep getting an error about the parent field not being able to be null when trying to delete the child. If I set nullable to false on the parent field in the child object, my parent disappears.

I thought I understood how this was supposed to work, but obviously not.

I have:

@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
}

In the below snippet, readerRepository.save(reader) is where the org.hibernate.PropertyValueException: not-null property references a null or transient value: com.me.project.entity.TBRList.reader exception is happening.

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;
        }
    }
}

I tried to also set reader to null in TBRList and delete it via the tbrListRepository , but the same thing happened. In fact, I've tried too many things to remember them all (I try to ask questions as a last result after hours of searching and trying things).

What am I doing wrong with trying to have a Parent/Child relationship, where I don't want Child.parent to be null, and I want to be able to delete a child from the parent without deleting the parent in the process?

I created the same classes and i get this result to execute as you want:

@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 ;


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM