【问题标题】:How to use EntityManager from @PrePersist?如何使用 @PrePersist 中的 EntityManager?
【发布时间】:2011-07-13 03:36:29
【问题描述】:

我有这个“模式”的“发布”实体/表:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
int id;

@GeneratedValue(strategy = GenerationType.AUTO)
private Integer postId;

private Integer revisionId;
private Boolean isCurrentRevision;

因此,表格包含帖子,每个帖子都有多个修订版,但只有其中一个(对于每个帖子)是最新的。

现在,假设我想保留现有帖子的另一个修订版(即更新帖子):

我需要为此 postId 找到现有的最高修订 ID,将其递增并将其设置为修订 ID。此外,这是新的当前版本,因此应相应标记,但以前的当前版本也应取消标记。

但是我该怎么做呢?我觉得这真的应该是实体实现的一部分,但另一方面我需要 EntityManager 来做到这一点。但是我找不到注入 EntityManager 实例的方法(保证存在)。

有可能吗?你如何实现这样的场景?谢谢!

【问题讨论】:

    标签: java jpa jpa-2.0 eclipselink


    【解决方案1】:

    很遗憾,您的建议没有干净、便携的方式。 JPA 2 规范 (JSR 317) 声明如下:

    一般来说,可移植应用程序的生命周期方法不应调用 EntityManager 或查询操作,访问其他实体实例,或修改内部的关系 相同的持久化上下文。

    就实现而言,Hibernate 明确禁止它:

    回调方法不得调用 EntityManager 或 Query 方法!

    我知道这并不是您真正希望的,但您似乎必须将修订管理责任分配给实体类的客户端。

    【讨论】:

    • 谢谢。我的解决方案是更改数据库架构,这样就不需要 EntityManager。
    【解决方案2】:

    这可能是传输对象模式的好地方。我们通常这样做:
    1. 将帖子实体转换为帖子传输对象
    2. 保存帖子后,我们将选择最高的 revisionId,增加它并创建一个新实体

    或者,您可以更新当前帖子并将条目添加到历史记录表(甚至可以在单独的数据库中)。因此,您可以使 post 表尽可能小以获得更好的性能,因为大多数情况下无论如何都需要当前版本的 post。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 2011-05-07
      相关资源
      最近更新 更多