Как каскадно вставить дочерние объекты, когда дочерний имеет составной ключ - PullRequest
0 голосов
/ 30 октября 2019

Я начинаю с того, что JPA исходит от EF, и попытался сделать простую вставку основной детали, в которой дочерний элемент имеет составной ключ.

Файл foo вставлен правильно (без ошибок, Hibernate просто печатает вставку в Fooзаявление), но планка просто игнорируется. Я нашел этот вопрос , где отношение определено в ключе, но я также не смог заставить его работать (та же проблема, что и в моем исходном решении, без исключений, просто нет дочерней вставки).

Мой код в настоящее время выглядит следующим образом:

@Entity
public class Foo {
    @Id
    private String fooID;

    @OneToMany(mappedBy = "foo")
    private List<Bar> bars = new ArrayList<>();

    // getter, setter,...
}

@Entity
public class Bar {

    @EmbeddedId
    private BarId id;

    public Bar(){
        this.id = new BarId();
    }

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @MapsId("fooID")
    @JoinColumn(name = "fooID", referencedColumnName = "fooID")
    private Foo foo;

    public void setFooId(String fooId){
        this.id.setFooId(fooId);
    }

    public void setBarNo(int barNo){
        this.id.setBarNo(barNo);
    }

    // other getter, setter,...
}

@Embeddable
public class BarId implements Serializable {
    private String fooID;
    private int barNo;

    // getter, setter, hashCode, equals,...
}

// ...
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();

Foo newFoo = new Foo();
newFoo.setFooID("baz");

Bar newBar = new Bar();
newBar.setFooId(newFoo.getFooId()); // even necessary?
newBar.setBarNo(1);
newBar.setFoo(newFoo);

newFoo.getBars().add(newBar);

em.persist(newFoo);
em.getTransaction().commit();

Я использую JPA 2.2 с Hibernate 5.4, если это что-то меняет.

Чтобы лучше уточнить, что мне нужно (длявсе, кто знает немного EF):

foo.HasKey(f => f.FooID);
foo.HasMany(f => f.Bars).WithOne(b => b.Foo).HasForeignKey(b => b.FooID);

bar.HasKey(b => new {b.FooID, b.BarNo});

Что я должен изменить, чтобы заставить это работать? Или я использую JPA совершенно неправильно с самого начала?

1 Ответ

0 голосов
/ 02 ноября 2019

Разобрался: cascade = CascadeType.PERSIST должен быть размещен на главной стороне, а не на стороне детализации отношения следующим образом:

@OneToMany(mappedBy = "foo", cascade = CascadeType.PERSIST)
private List<Bar> bars = new ArrayList<>();
...