We have an entities like this:
public User {
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "user_id", insertable = true, updatable = true)
@ElementDependent
private List<Item_x> item_x_list = new ArrayList<Item_x>();
}
public Item_x {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", insertable = true, updatable = true)
@Element(name = "user_id", required = false)
private Users user;
}
Whenever I add/remove items to User.item_x_list and then persist the User entity using em.merge(User.INSTANCE) the Item_x.user property is NULL.
I am loading the Item_x.user property with a JOIN FETCH query to make sure the attribute is loaded (when I need it). However: the Item_x.user property is NULL even with FETCH JOIN if you have performed a merge on the User Entity.
I tried to workaround by refreshing the Item_x.INSTANCE but when I call:
em.refresh(Item_x.Instance);
=> user is null.
Looking in the database I of course can see that the user is NOT null in the Item_x.
How can I force OpenJPA to correctly load the user in Item_x ? Why is OpenJPA not filling correctly the Item_x.user property / ignores the JOIN FETCH statement?
It looks like the problem is that you've created two uni-directional relationships instead of a bi-directional relationship. One of your classes needs to define a mappedBy relation to the other class, which defines the other class as the "owner" of the relationship. For example, you can change your example above to define Item_x as the owner as follows:
public User {
@OneToMany(targetEntity = Item_x.class, mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@ElementDependent
private List<Item_x> item_x_list = new ArrayList<Item_x>();
}
public Item_x {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", insertable = true, updatable = true)
@Element(name = "user_id", required = false)
private Users user;
}
More information is available in the OpenJPA documentation, but they're missing examples which would make it more clear.