Am new to JPA and I have learned a lot from this forum. I have this problem.
I have 2 tables (Members and Member_next_of_kin). memberId is auto incremental column in members table
The Member_next_of_kin has a referenced column memberId from members tabke which is Mandatory
I have this method to create new member.
public void addMember(Members member) {
try {
createNewMember(member);
nok.setMemberId(getMemberId());
addNextOfKin(nok);
} catch (Exception e) {
context.setRollbackOnly();
}
}
public Members createNewMember(Members member) {
memberFacade.create(member);
return memberId;
}
My aim is to persist the create Member and return back the created memberId and use it to insert in nextofkin table.
please show me how to do this within the transaction. Memberid is returning null.
答案 0 :(得分:2)
在JPA中,您将使用关系建模所需的行为 - 在您的情况下为@OneToMany
,而不是对另一实体的标识符的简单引用。
JPA是一种对象关系映射,因此请考虑OO设计。 现在让我们根据您提供的信息尽可能简单地对此进行建模:
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@OneToMany(mappedBy="member")
private Set<NextOfKin> kindred;
}
和
@Entity
public class NextOfKin {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Member member;
}
现在,这就是JPA复杂性的一部分,如果您首先尝试基本掌握JPA中的一些重要概念,那么这是最好的。
我们在此处建模的是JPA术语中的双向一对多/多对一关系。在SQL中,NextOfKin表将获取一个poiting到Member表的外键。每个双向关系都有一个拥有方和一个反面。所有方可能会也可能不会对应两个实体之间的自然关系。在JPA中,owner是实体,负责管理数据库中的关系(外键)。根据JPA规范,在双向一对多关系的情况下,许多方应始终是拥有方 - 在您的情况下NextOfKin
。我们使用mappedBy
@OneToMany
属性指定反面只有通过对所有者执行数据库操作才能正确管理数据库中的关系。有多种方法可以实现您需要的功能:
让我们假设您从一个空数据库开始,没有成员,也没有NextOfKins。您的示例可以像这样实现。
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
在此之后,DB中的关系应该是正确的 - NextOfKin表有一个条目,生成的Long Id和FK指向Member表中的条目。数据库中的信息是正确的,即使在Java中,成员在其同类集合中没有任何元素。 您可以通过从数据库加载成员来验证它,例如
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())
还有其他选项,例如,您可以在关系中添加Cascade
行为,以便在Member上执行的数据库操作将级联为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);
另一个选择是使关系单向 - 以便NextOfkin与Member没有关系。因此,所有操作都将在Member表上执行。
有关JPA拥有/反面的更多信息,请查看SO的一些常见问题,例如: In a bidirectional JPA OneToMany/ManyToOne association, what is meant by “the inverse side of the association”?
JPA和ORM一般来说是一个复杂的主题,我强烈建议您花一些时间阅读文档或一本好书。 在我看来,生产性地使用JPA所需的最低知识是基本的实体映射,关系映射,获取策略,对所有者/逆概念的理解和级联。
您可以在线免费找到许多来源,具有不同程度的复杂性 一些有用的资源:
祝你好运,不要忘记,总有不止一个如何实现你的目标。如果您发现JPA过于复杂,您可以尝试其他一些Java DB框架,如jOOQ或mybatis。