我是JPA的新手,我从这个论坛学到了很多东西.我有这个问题.
我有2个表(成员和Member_next_of_kin). memberId是成员表中的自动增量列
Member_next_of_kin具有来自成员tabke的引用列memberId,这是必需的
我有这个方法来创建新成员.
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;
}
我的目标是坚持创建成员并返回创建的memberId并使用它插入nextofkin表.
请告诉我如何在交易中做到这一点. Memberid返回null.
最佳答案 在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.我们使用@OneToMany的mappedBy属性指定反面只有通过对所有者执行数据库操作才能正确管理数据库中的关系.有多种方法可以实现您所需的功能:
让我们说你从一个空数据库,没有成员和没有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())
还有其他选项,例如,您可以向关系添加级联行为,以便在Member上执行的DB操作将级联为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所需的最低知识是基本的实体映射,关系映射,获取策略,对所有者/逆概念的理解和级联.
您可以在线免费找到许多来源,具有不同的复杂程度.
一些有用的资源:
> Java Persistence on Wiki books
> JPA 2.1 Spec
> Oracle’s Java EE 6 JPA tutorial
祝你好运,别忘了,总有不止一个如何实现你的目标.如果您发现JPA过于复杂,您可以尝试其他一些Java DB框架,如jOOQ或mybatis.