Bee-j
Bee-j

Reputation: 44

JPA child doesn't persist when parent persist method is called

This child entity is not persisted along with the parent when em.persist is called

@Entity
@Table(name="Z_PARENT")
public class Parent {

@Id
 @TableGenerator(name="parentIDGen", table="Z_JPA_ID_GEN",
 pkColumnName="ID_STRING", valueColumnName="ID_GEN",
 pkColumnValue="Z_PARENT")
 @GeneratedValue(strategy=GenerationType.TABLE, generator="parentIDGen")
private int id;

@Column(name="NAME")
private String name;


@OneToMany(mappedBy="parent",cascade={CascadeType.ALL})
Set<Child> children;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}



@Override
public int hashCode() {
......
}

@Override
public boolean equals(Object obj) {
........
}

public Set<Child> getChildren() {
    return children;
}

public void setChildren(Set<Child> children) {
    this.children = children;
}

}

Child Table

@Entity
@Table(name="Z_CHILD")
public class Child {

@Id
@TableGenerator(name="childIDGen", table="Z_JPA_ID_GEN",
pkColumnName="ID_STRING", valueColumnName="ID_GEN",
pkColumnValue="Z_CHILD")
@GeneratedValue(strategy=GenerationType.TABLE,generator="childIDGen")
private int id;

@Column(name="NAME")
private String name;

@Column(name="PARENT_ID")
private int parentID;

@ManyToOne
@JoinColumn(name="PARENT_ID",referencedColumnName="ID")
private Parent parent;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getParentID() {
    return parentID;
}

public void setParentID(int parentID) {
    this.parentID = parentID;
}

@Override
public int hashCode() {
.....
}

@Override
public boolean equals(Object obj) {
.....
}

public Parent getParent() {
    return parent;
}

public void setParent(Parent parent) {
    this.parent = parent;
}

}

persisting code

 em.getTransaction().begin();
 Parent parent= new Parent();
 parent.setName("Parent1");
 Set<Child> children=new HashSet<Child>();
 Child child1=new Child();
 child1.setName("Child1");
 children.add(child1);
 parent.setChildren(children);
 em.persist(parent);
 em.getTransaction().commit();

Error generated by openJPA, I am using DB2

Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: DB2 SQL Error: SQLCODE=-530, SQLSTATE=23503, SQLERRMC=ADMINISTRATOR.Z_CHILD.CC1369070983676, DRIVER=3.58.81 {prepstmnt 864433030 INSERT INTO Z_CHILD (id, NAME, PARENT_ID) VALUES (?, ?, ?) [params=(int) 450, (String) Child1, (int) 0]} [code=-530, state=23503] at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:281) at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:257) at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$1000(LoggingConnectionDecorator.java:72) at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:1199)

Upvotes: 0

Views: 3147

Answers (1)

Gab
Gab

Reputation: 8333

SQLCODE : -530 THE INSERT OR UPDATE VALUE OF FOREIGN KEY constraint-name IS INVALID

You must understand that the generated ID is set in the entity instance in the post persist phase. JPA is not yet able to propagate the generated parent ID to the children. So you must set it yourself

 em.getTransaction().begin();
 Parent parent= new Parent();
 parent.setName("Parent1");
 em.persist(parent); // here parent id is valuated
 Set<Child> children=new HashSet<Child>();
 Child child1=new Child();
 child1.setName("Child1");
 child1.setParentID(parent.getId());
 children.add(child1);
 parent.setChildren(children);
 em.merge(parent);
 em.getTransaction().commit();

Upvotes: 2

Related Questions