In JPA you would model the required behavior with a relationship - in your case @OneToMany
instead of a plain reference to the identifier of the other entity.
JPA is an object-relational mapping, so think in terms of OO design.
Now lets try to model this as simply as possible based on the information you provided:
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@OneToMany(mappedBy="member")
private Set<NextOfKin> kindred;
}
and
@Entity
public class NextOfKin {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Member member;
}
Now this is where some of JPA complexity comes to place, and it is for the best if you first try to get a basic grasp of some of the important concepts in JPA.
What we have modeled here is a bidirectional one-to-many/many-to-one relationship in JPA terms. In SQL, the NextOfKin table will get a foreign key poiting to Member table. Every bidirectional relationship has one owning side and one inverse side. Owning side may or may not correspond to the natural relationship between the two entities. In JPA, owner is the entity, that is responsible for management of the relationship(foreign keys) in the database. According to JPA spec, in case of bidirectional one-to-many relation, the Many side should always be the owning side- in your case the NextOfKin
. We designate the inverse side by using mappedBy
attribute of @OneToMany
Only by performing DB operations on the owner can you correctly manage the relationship in DB. There are multiple ways how to achieve the functionality you require:
Lets say you start with an empty DB, no Members and no NextOfKins. Your example could be implemented like this.
Member newMember = new Member();
NextOfKin nok = new NextOfKin();
createNewMember(newMember);//here something like em.persist() should happen
//after the save, the member.getId() will return a generated Long identifier
//because we annotated the id attribute with @GeneratedValue
//NextOfkin is the owner, therefore we need a correct in
memory relationship from its point of view
nok.setMember(newMember);
createNewNok(nok);//again persist the entity
//end of transaction
After this, the relationship in DB should be correct - the NextOfKin table has one entry, with generated Long Id and a FK pointing to the entry in Member table. The information in the DB is correct, even though in Java, Member did not have any elements in its kindred collection.
You can verify it by loading the member from DB e.g.
Member fromDB = entityManager.find(Member.class, newMember.getId());
assertTrue("Member should have exactly one next of kin now",
fromDB.getKindred().size() == 1);
//and also from the other side
NextOfKin nokFromDB = entityManager.find(NextOfKin.class, nok.getId());
assertTrue("next of kin should have a member",
nokFromDB.getMember().getId() == newMember.getId())
There are other options, for example, you could add a Cascade
behaviour to the relationship, so that a DB operation performed on Member would be cascaded to kindred:
//...in Member
@OneToMany(cascade=CascadeType.ALL, mappedBy="member")
//... saving member will now save NextOfKin as well,
//but remember, we have to set the correct information in memory
// from the point of view of the owner
Member newMember = new Member();
NextOfKin nok = new NextOfKin();
nok.setMember(newMember);
createNewMember(newMember);
Another option is to make the relationship unidirectional - so that the NextOfkin would not have a relation to Member. Therefore all operations would be performed on the Member table.
For more information on JPA owning/inverse side have a look at some popular questions here at SO , e.g. In a bidirectional JPA OneToMany/ManyToOne association, what is meant by “the inverse side of the association”?
JPA and ORM in general is a complex subject, and I highly recommend spending some time with the documentation or a good book.
The minimum knowledge that is, in my opinion, required to productively use JPA is basic Entity mapping, relationship mappings, fetching strategies, understanding of owner/inverse concept and cascading.
You can find many sources online and for free, with varying levels of complexity.
Some useful resources:
Good luck and do not forget, there is always more than one of how to achieve your goals. If you find JPA too complex, you can try some other Java DB frameworks like jOOQ or mybatis.