JPA удалить дочерний элемент без удаления родителя - PullRequest
0 голосов
/ 08 июля 2020

Я использую Spring Boot 2.3.0.

У меня есть отношение ManyToOne с одной стороны и отношение OneToMany с другой стороны. Один родитель для многих детей, но много детей для одного родителя. Я пытаюсь удалить детей, не затрагивая родителя. У меня есть nullable = false на дочерней стороне для родительского поля, потому что я не хочу, чтобы в таблице parent_to_child были случайные нули для родительского. Я хочу, чтобы такие вещи применялись и меня ловили.

Когда я делаю readerRepository.save(reader) после удаления одного из TBRList элементов (это дочерний элемент) из List<TBRList> в объекте Reader (это родительский элемент), я продолжаю получать сообщение об ошибке, что родительское поле не может иметь значение NULL при попытке удалить дочерний элемент. Если я установил значение false для родительского поля в дочернем объекте, мой родитель исчезнет.

Я думал, что понял, как это должно работать, но, очевидно, нет. 1014 *

@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 и delete это через tbrListRepository, но произошло то же самое. Фактически, я перепробовал слишком много вещей, чтобы их все запомнить (я пытаюсь задавать вопросы в качестве последнего результата после нескольких часов поиска и проб).

Что я делаю не так, пытаясь иметь Родителя? / Дочернее отношение, где я не хочу, чтобы Child.parent имел значение NULL, и я хочу иметь возможность удалить дочерний элемент от родителя без удаления родителя в процессе?

1 Ответ

0 голосов
/ 09 июля 2020

Я создал те же классы, и я получаю этот результат для выполнения, как вы хотите:

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


}
...