gpt4 book ai didi

jpa - 实体 session bean - 将数据持久化到表中并使用创建的 Id 来持久化另一个表

转载 作者:行者123 更新时间:2023-12-01 03:37:34 25 4
gpt4 key购买 nike

我是 JPA 的新手,我从这个论坛学到了很多东西。我有这个问题。

我有 2 个表(Members 和 Member_next_of_kin)。 memberId 是成员表中的自动增量列

Member_next_of_kin 有一个来自 members 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 表将获得指向 Member 表的外键。每个双向关系都有一个 拥有方和一个 反面 .拥有方可能对应也可能不对应两个实体之间的自然关系。在 JPA 中,所有者是实体,负责管理数据库中的关系(外键)。根据 JPA 规范,在双向一对多关系的情况下,多方应始终是拥有方 - 在您的情况下为 NextOfKin .我们使用 mappedBy 指定反面 @OneToMany 的属性只有对owner进行DB操作,才能正确管理DB中的关系。有多种方法可以实现您需要的功能:

假设您从一个空数据库开始,没有成员也没有 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 表中的条目。 DB 中的信息是正确的,即使在 Java 中,Member 的同类集合中没有任何元素。
您可以通过从数据库加载成员来验证它,例如
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 执行的数据库操作将级联到亲属:
//...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。

    关于jpa - 实体 session bean - 将数据持久化到表中并使用创建的 Id 来持久化另一个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33445838/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com