在Hibernate-Envers中如何使实体的早期版本成为最新版本

问题描述 投票:0回答:1

我的应用程序使用Hibernate-Envers 4.3.11

  • 我将音乐文件加载到我的数据库中,其元数据(例如专辑标题,艺术家)表示为经过审核的Song类
  • 然后app以各种方式编辑元数据,并写回Song类(每次提交的会话创建另一个修订版)
  • 然后通常在最后将更改从当前Song类写回文件本身。
  • 但如果在预览模式下运行,则不会向该文件写入任何内容。所以我希望该文件的Song类的最新版本现在包含与最初加载文件时创建的版本相同的元数据。

目前我通过获取Song的第一个版本并将其保存的数据复制到最新版本的Song来实现此目的。但有没有办法我可以说这个早期版本并将其作为最新版本。

更新

我现在正在实施纳罗斯的答案。所以现在我有一个名为SongFile的类,它总是代表磁盘上音乐文件的内容,这是@Audited(由Envers提供),主要ID是@GeneratedValue。

然后我们有一个名为Song的类,在创建一个SongFile实体后,我们创建一个等效的Song实体。这不会被审核,主要ID是手动设置的,我们将primaryId和所有元数据设置为与Song类相同。

然后,应用程序将元数据修改为Song。

然后在结束时如果处于预览模式,我们只是比较Song和SongFile之间的差异并生成报告。

如果在Real保存模式下,我们比较Song和SongFile之间的差异并生成报告并将更改保存回文件和SongFile。

这很有效,解决了许多问题。

但是我有一个问题,音乐文件也可以存储多个图像(jpeg等),我们用表示图像的CoverImage类来模拟它,而一个CoverArt类在Song和CoverImage之间提供1:M链接,还存储一个名称属性。

现在的问题是我创建了一个由SongFile使用的CoverArtFile类,它使用@GeneratedValue和Song使用的不自动的CoverArt类。

当最初加载文件并创建SongFile和Song时,这可以正常工作,将自动化值从任何CoverArtFile类复制到CoverArt类

但是,如果我们没有开始使用它然后它被应用程序添加我们就会失败,因为CoverArt类不会自动生成主键,并且我无法安全地生成一个以防它被现有的CoverArtFile类使用(或者将在未来)。

如果我有使用自动值的CoverArt,那么它不会与其关联的CoverArtFile类使用的值相同。

我该怎么办?

java hibernate hibernate-envers
1个回答
1
投票

首先,没有自动方式来执行您的请求。此过程必须完全手动并在应用程序中进行编码,因为有许多实体细微差别和业务考虑因素最好由应用程序决定和处理。

所以最好的方法就是这样做

  1. 从要还原到的审核历史记录中获取所需的修订。
  2. 从Hibernate获取现有实体。
  3. 将(2)中现有实体中的值设置为(1)中所需修订版本中的值。
  4. 合并修改后的实体。

可能有用的另一个想法是考虑分离预览和非预览的概念。我的意思是你有两个实体而不是一个Song。你有一个代表高度的voltile版本用于预览,另一个代表用于表示文件内容的较少的voltile非预览版本。

在这种方法中,当您修改预览变体时,您只需创建一个包含Envers的更改日志,以获取可能对文件进行但不是由于预览模式的内容。修改非预览变量时,您将为文件内容创建更改日志。

这里需要注意的是你的业务逻辑应该也可以在这个用例中同步预览变量,这样预览和非预览都有相同的内容,所以基本上加载预览实体,修改它以匹配非预览然后保存更改也是如此。

如果两种实体类型都具有公共主键或自然ID,则应该很容易管理并允许您生成所有类型的报告并保持一致的历史记录而不会混淆问题。

UPDATE

添加有关更新的答案;在这里,您可能希望为所有实体使用生成的标识符,并让SongCoverArt实体保持对审计实体的引用或至少存储主键值。

举个例子

@Entity
public class Song {
  @Id
  @GeneratedValue
  private Long id;
  @OneToOne
  private SongFile songFile;      
}

或者更简单

@Entity
public class Song {
  @Id
  @GeneratedValue
  private Long id;
  private Long songFileId;
}

我们的想法是,您的非基于文件的实体通过关联(例如@OneToOne)维护与文件侧的关系,或者存储关联实体的标识符,以便您可以确定是否需要获取/复制或构造/插入。

© www.soinside.com 2019 - 2024. All rights reserved.