I have two really simple objects and one object should contain the other one in an "one-to-many" relation in a set. The objects get inserted correctly in the database, but the foreign key in the "children" table is always "null".
I can't figure out why:
This is the test-object and it hold the children in its set:
@Entity
@Table(name="test")
public class TestObj {
public TestObj(){}
private Long id;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private Set<Children> children = new HashSet<Children>();
@OneToMany(mappedBy = "testObj", cascade = CascadeType.ALL)
public synchronized Set<Children> getChildren() {
return children;
}
public synchronized void setChildren(Set<Children> children) {
this.children = children;
}
public void addChildren(Children child){
children.add(child);
}
}
This is the children object and it holds an back-link to the "TestObj":
@Entity
@Table(name = "children")
public class Children {
public Children(){}
private Long id;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private TestObj testObj;
@ManyToOne
@JoinColumn
public TestObj getTestObj() {
return testObj;
}
public void setTestObj(TestObj testObj) {
this.testObj = testObj;
}
}
I persist this objects with this code:
EntityManagerFactory entityManagerFactory = HibernateEntityMangerSingelton.getEntityManagerFactory();
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
TestObj user = new TestObj();
Children child = new Children();
user.addChildren(child);
try {
entityManager.persist(user);
entityManager.getTransaction().commit();
} catch (Exception e) {
System.out.println(e);
}finally{
entityManager.close();
}
Can some explain me why this is happening?
It's quite simple: you never initialize the testObj
field in Children
(which should be named Child, BTW). Children.testObj
is the owner of the association, and is the field that is mapped to the join column, so if it's null, the join column will be null.
I had a similar problem which i solved by calling setter of the owner side. The 2 metods seting and adding the children to the TestObj should be altered like this, so that the TestObj is initialized at the owner side:
public synchronized void setChildren(Set<Children> children)
{
this.children = children;
for(Children child : children)
{
// initializing the TestObj instance in Children class (Owner side) so that it is not a null and PK can be created
child.setTestObj(this);
}
}
The second method:
public void addChildren(Children child)
{
children.add(child);
//Intializing the TestObj instance at the owner side
child.setTestObj(this);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With