我的問題很多關係是相當類似以下內容:JPA不會從一個插入新的孩子的,當我們使用合併
JPA: How do I add new Items to a List with a OneToMany annotation
Why merging is not cascaded on a one to many relationship
JPA with JTA: Persist entity and merge cascaded child entities
我也有一個看在Wikibooks,但仍然無法解決我的問題
所以,我的問題是我有一個父類與孩子,當我添加一個新的孩子,並使用entityManager.merge(父)來更新新的孩子沒有插入,我得到一個錯誤的空主鍵。
我能夠創建一個父母與我想要的任何孩子,並更新這些孩子,但不添加一個新的孩子。
例子:
@Entity
public class Parent {
private String name;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private List<Child> children;
}
@Entity
public class Child {
private String name;
@ManyToOne
private Parent parent;
}
如果我創建了一些孩子,它工作正常父。如果我更新孩子的屬性它工作正常,如果我添加一個新的孩子父母它不起作用。
public void foo(){
Parent parent = new Parent();
List<Child> children = new ArrayList<Child>();
children.add(new Child());
children.add(new Child());
children.add(new Child());
parent.setChildren(children);
//it works
entityManager.persist(parent);
//and lets say that I have updated some attributes
changeAttributesValues(parent);
changeAttributesValues(children);
//it still working and the values are updated properly
entityManager.merge(parent);
//but if I add some child
List<Child> children = parent.getChildren();
children.add(moreOneChild);
parent.setChildren(children);
entityManager.merge(parent);
//here I got an error saying that jpa cannot insert my attribute because my PK is null
}
注:我的PK是一個複合鍵(可以在這個例子中說,這是idFromParent + idCompany)提前
感謝。
EDIT
我解決了這個問題取出複合物鍵和添加一個自動生成的ID。我發佈了我的真實代碼以及我所做的工作。有了這個代碼,
@Entity
public class Serie implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SERIE_ID_SEQ")
@SequenceGenerator(name = "SERIE_ID_SEQ", sequenceName = "real.serie_id_seq")
@Column(name = "idserie")
private Long id;
@Basic
@Column(name = "nmserie")
private String nmSerie;
@OneToMany(mappedBy = "serie", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private List<SerieExercise> serieExercises;
@ManyToOne
@JoinColumn(name = "idtrainning")
private Trainning Trainning;
}
@Entity
public class SerieExercise implements Serializable{
@Basic
@Column(name = "nrrepetition")
private int nrRepetition;
@Column(name = "tminterval")
@Temporal(TemporalType.TIMESTAMP)
private Date tmInterval;
@Id
@Basic
@Column(name = "nrorder")
private Integer nrOrder;
@Id
@ManyToOne
@JoinColumn(name = "idexercise")
private Exercise exercise;
@Id
@ManyToOne
@JoinColumn(name = "idserie")
private Serie serie;
}
有了這個代碼,我得到這個錯誤,當我嘗試在我的列表中插入一個更SerieExercise:
Caused by: org.postgresql.util.PSQLException: ERRO: ERROR: null value in column "nrorder" violates not-null constraint
Detail: Failing row contains(null, 10, null, null, null).
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:420)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:366)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeUpdate(WrappedPreparedStatement.java:493)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
... 132 more
我有調試和值之前,我打電話entityManager.merge( )不爲空。我正在使用休眠提供程序。我可以在我的列表中插入一份SerieExercise,並且可以更新這些值,但無法在列表中添加新的SerieExercise。
要解決我做了這些變化:
@Entity
public class SerieExercise implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SER_EXER_ID_SEQ")
@SequenceGenerator(name = "SER_EXER_ID_SEQ", sequenceName = "realvida.ser_exer_id_seq")
@Column(name = "idserieexercicio")
private Long id;
@Basic
@Column(name = "nrrepetition")
private int nrRepetition;
@Column(name = "tminterval")
@Temporal(TemporalType.TIMESTAMP)
private Date tmInterval;
//@Id
@Basic
@Column(name = "nrorder")
private Integer nrOrder;
//@Id
@ManyToOne
@JoinColumn(name = "idexercise")
private Exercise exercise;
//@Id
@ManyToOne
@JoinColumn(name = "idserie")
private Serie serie;
}
有誰知道爲什麼會發生?我可以使用複合鍵進行這項工作嗎?
讓我知道你是否需要更多信息。
您是否在moreOneChild中設置了父級?你能舉一個更簡單的例子嗎? –
對不起,現在編輯代碼。看起來問題與組合主鍵有關。我仍在研究。 –
我可以讓你的保存序列工作,所以沒有什麼不對。你需要製作一個可重現的問題。如果你有一個複合主鍵,並且你得到了一個關鍵違規,那就需要你的問題的基礎 –