В JPA вставьте дочерний элемент и сохраните и удалите дочерний элемент немедленно, не удаляя дочерний элемент в базе данных - PullRequest
0 голосов
/ 22 марта 2020

У меня есть родительский объект, содержащий список дочерних элементов.

  • Родитель A содержит дочерний элемент A1
  • В транзакции
    • Добавление дочернего элемента A2 в список дочерних элементов
    • Сохранить (без гриппа sh)
    • Очистить дочерний список (очистить коллекцию)
    • Добавить дочерний A3
    • Сохранить и грипп sh

В результате:

  • В базе данных есть две дочерние записи: (A1 удален)
    • A2 без родительского элемента info (== null)
    • A3 с родительской информацией

Может ли кто-нибудь указать мне документ, показывающий, как работает JPA, не добавляя родительскую информацию для A2?

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @Fetch(FetchMode.SELECT)
    @JoinColumn(name = "parent_id")
    List<Child> children;

    @Version
    private Long recordVersion;
}
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "parent_id", insertable = false, updatable = false)
    private Parent parent;

    @Version
    private Long recordVersion;

    public String toString() {
        return "Child[id=" + id + ";name=" + name + "]";
    }
}
@Transactional
    public void addChild(Long parentId, String childName) {
        Parent parent = getParent(parentId);

        Child child = new Child();
        child.setName("A2");
        List<Child> children = Arrays.asList(child);
        parent.getChildren().addAll(children);
        parentRepository.save(parent);

        parent = getParent(parentId);
        parent.getChildren().clear();

        Child child1 = new Child();
        child1.setName("A3");
        List<Child> spaces1 = Arrays.asList(child1);

        parent.getChildren().addAll(spaces1);
        parentRepository.saveAndFlush(parent);
    }

Обновление 1: если я закомментирую parentRepository.save (parent); или заменить parentRepository.saveAndFlu sh (parent); в базе данных есть только A3.

1 Ответ

0 голосов
/ 22 марта 2020

Наиболее вероятная причина проблемы, с которой вы сталкиваетесь, заключается в том, что двунаправленная связь не отображается правильно. Фактически, вы объявили две совершенно не связанные ассоциации, а затем заставили их разделить столбец соединения.

Чтобы правильно отобразить двунаправленную ассоциацию «один ко многим», необходимо объявить сторону «один» как обратную сторону следующим образом:

@OneToMany(mappedBy = "parent")
@Fetch(FetchMode.SELECT)
List<Child> children;

Обратите внимание, что в таком случае Сценарий Child является владельцем ассоциации. Изменения Parent.children полностью игнорируются.

Поскольку вам кажется, что вы хотите иметь возможность управлять ассоциацией исключительно с помощью Parent.children, вы, вероятно, захотите сделать Parent владельцем, удалив вместо этого свойство Child.parent (таким образом, изменив ассоциацию к однонаправленному).

Обратите внимание, что две вышеуказанные опции являются единственными действительными сопоставлениями. Вы не можете одновременно сделать обе стороны ассоциации владельцем, а в двунаправленной ассоциации «один ко многим» сторона «101» не может быть стороной-владельцем.

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