【问题标题】:Persisting/saving a JPA entity's relationships before that entity itself在该实体本身之前持久/保存 JPA 实体的关系
【发布时间】:2013-03-25 03:33:32
【问题描述】:

我有一个 @OneToMany JPA 关联,其中一个 Curriculum 实例具有多个 WorkExperience 实例。

Curriculum JPA 实体:

@Entity
public class Curriculum {
    ...
    @OneToMany
    private Set<WorkExperience> workExperiences;
    ...

WorkExperience JPA 实体:

@Entity
public class WorkExperience {
...

我最初想将课程及其 WorkExperiences 持久化到一个 entityManager 调用的 persist 方法中。

但是,鉴于我如何设计 Web UI 的操作流程,我现在想知道是否可能无法实现另一种情况,即:

  • 先将 WorkExperiences 持久化到 db,然后当用户填写主课程实体详细信息后,到:

  • 将现有的 WorkExperience 实例(已在 db 中)设置为 Curriculum 实例(尚未在 db 中)并

  • 坚持整个对象图:课程及其工作经验。

这有意义吗?我想到了几个缺点,例如如果用户选择不保留 Curriculum 实例会发生什么?如何清理 WorkExperience 表中的悬空线?

是否有替代方案或更好的模式?例如,在用户验证表单之前预先保存课程实例是个好主意吗?

【问题讨论】:

    标签: java jpa spring-mvc


    【解决方案1】:

    我会在Curriculum 上定义一个级联,因为WorkExperience 似乎是一个依赖实体。

    然后在 UI/控制器中使用新的/分离的实体,直到用户决定提交(最后一个)表单。然后持久化Curriculum 和相关的WorkExperience 实体也将在同一个事务提交期间持久化。

    @OneToMany(cascade=CascadeType.ALL)
    private Set<WorkExperience> workExperiences;
    

    【讨论】:

    • 感谢科斯特亚的回复。好的,但是在课程最终保存之前,我应该将分离的 WorkExperience 实例存储在哪里?
    • @balteo 将它们放在分离的课程实体内的Set 中,这样持久化将被级联。我不熟悉 Spring MVC,但我假设您有一个用于视图的控制器,该控制器已实例化并且具有处理表单提交的方法。这个控制器是我在持久化之前存储课程实体的地方。对于用户创建新实体的视图,我通常在控制器实例化期间创建一个空实体,对其进行操作,然后在提交成功后将其持久化。
    • 嗯。 Spring MVC 控制器是单例的。将状态放在单例中并不是一个好主意。我考虑过使用会话进行存储,但这也不是一个好主意...
    • @balteo Singletons?这使问题变得更加复杂。我认为使用会话范围的 bean 并不是一个坏主意。您可以注入一个包含课程的会话范围 bean,如 here 解释的那样。不过,我不是 Spring 细节的好顾问 - 我的主要专长是使用 JPA(使用 JSF,其中控制器通常是有状态的),我认为您的问题主要是关于 JPA。对不起,如果我的回答没有帮助。
    • @balteo 您可以保存一个新的课程实例,并在每次添加新的 WorkExperience 时重新获取、更新和合并它。然而,这意味着应用程序实际上是有状态的。通过坚持每个更改,您只需将状态推送到数据库中。这可能会对性能产生不良影响,因此如果可能的话,我更愿意将状态保留在应用程序中,尤其是在状态经常更改的情况下。我不确定 Spring 中是否存在中间范围,例如 JSF/CDI 中的 View 或 Conversation 范围。如果有,显然比会议更可取。
    猜你喜欢
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    • 2019-09-20
    • 2016-06-10
    • 2011-07-16
    • 2015-07-27
    相关资源
    最近更新 更多