My question is pretty similar to the following:
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
I also had a look in Wikibooks but still not able to fix my problem
So, my problem is that I have a Parent class with childs, and when I add a new child and use entityManager.merge(parent) to update the new children are not inserted and I get an error of null primary key.
I'm able to create a Parent with whatever children I want, and update theses children, but not to add a new child.
Example:
@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;
}
If I create a Parent with some children it works fine. If I update the children's attributes it works fine, and if I add a new child to parent it does not work.
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
}
Note: My PK is a composite Key (lets say in this example that it is the idFromParent + idCompany)
Thanks in advance.
EDIT
I solved the problem removing the composite key and adding an auto generated ID. I'm posting my real code and what I have done to make it work. With this code,
@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;
}
With this code I get this error when I try to insert one more SerieExercise in my List:
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
I have debugging and the values before I call entityManager.merge() are not null. I'm using hibernate provider. I'm able to insert a Serie with whatever SerieExercise I want in my list, and able to update the values, but not able to add a new SerieExercise in my List.
To fix I made these changes:
@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;
}
Does anyone know why it happens? Can I make this work using a composite key?
Let me know if you need more info.