Сущность с CascadeType.ALL в OneToMany не сохраняется детьми - PullRequest
0 голосов
/ 27 января 2019

Я работаю со сторонней библиотекой, предоставленной нашей команде, в которой одна из сущностей имеет отношение OneToMany к сущностям того же самого типа.Я изменил имя объекта, чтобы оно оставалось анонимным.

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

Используется OpenJPA 2.4.0-ep2.0

@Entity
@Table(name =  Person.TABLE_NAME)
public class Person {
private Long parentUid;
private List<Person> children = new ArrayList<>();

@OneToMany(targetEntity = Person.class, cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@ElementJoinColumn(name = "PARENT_UID")
@ElementForeignKey
@ElementDependent
public List<Person> getChildren() {
    return this.children;
}

}

Когда я пытаюсь сохранить человека с детьми, сохраняется только основная сущность, а дети игнорируются.

Однако, если я изменю атрибут fetch на FetchType.EAGER, он сработает (сохраняется как родительский, так и дочерний).Насколько я понимаю, тип выборки влияет только на загрузку, а не на вставку.Любые идеи, почему это происходит?

Кроме того, есть ли способ заставить его работать при сохранении типа выборки FetchType.LAZY?

Я пробовал следующее (изменить сеттер):

protected void setChildren(final List<Person> children) {
    if (Objects.nonNull(children)) {
        for (Person child : children) {
            child.setParentUid(parentUid);
        }
        this.childItems = children;
    } else  {
        this.childItems = new ArrayList<>();
    }
}

1 Ответ

0 голосов
/ 08 мая 2019

Проблема в дочерней сущности, вы должны использовать аннотацию @ManyToOne в дочерней сущности.

добавить следующий код в Person:

public class person {
            .
            .

           @MantToOne(fetch=FetchType.LAZY)
           @JoinClolumn(name="PARENT_UID")
           private Person parent;

             public void setParent(Person parent){
             }
              .
              .

        }

, а затем пересмотреть код setChildren следующим образом:

 protected void setChildren(final List<Person> children) {
        if (Objects.nonNull(children)) {
            for (Person child : children) {
                child.setParent(this);
            }
            this.childItems = children;
        } else  {
            this.childItems = new ArrayList<>();
        }
    }

один важный момент: ، всегда тип выборки должен быть синхронизирован в родительском и дочернем типах.

...