如何从@PrePersist使用EntityManager?

时间:2011-03-10 23:55:10

标签: java jpa jpa-2.0 eclipselink

我使用此“架构”“发布”实体/表格:

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

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

private Integer revisionId;
private Boolean isCurrentRevision;

因此,表包含帖子,每个帖子都有多个修订,但只有它们(对于每个帖子)是最新的。

现在,假设我想继续修改现有帖子(即更新帖子):

我需要为这个postId找到最高的现有revisionId,增加它并将其设置为revisionId。这也是新的当前版本,所以应该相应地进行标记,但前一个版本也应该没有标记。

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

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

2 个答案:

答案 0 :(得分:5)

不幸的是,没有干净,便携的方式来解决你的建议。 JPA 2规范(JSR 317)声明如下:

  

通常,可移植应用程序的生命周期方法不应调用EntityManager   或查询操作,访问其他实体实例或修改其中的关系   相同的持久性背景。

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

  

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

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

答案 1 :(得分:0)

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

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