我有一个已经填充的 SQL 数据库,我想在其中添加 Javers 审计。jv_snapshot
在对特定对象运行初始更新之前,有没有办法用对象的当前状态初始化表?我发现我正在丢失以前的状态,因为jv_snapshot
表包含更新状态作为初始状态。我正在使用 hibernate/jpa 运行一个 spring boot 应用程序。
3 回答
根据数据库的大小,可能需要数小时或数天才能将每条记录与 Javers 同步,即使这些记录可能永远不会从初始状态更改。
它可能不是您正在寻找的东西,但它对我有用。
// UserService.java
@Autowired
private Javers javers;
@Autowired
private UserRepository userRepository;
public void updateUser(UserDTO user){
User existing = userRepository.findOne(user.getId());
// Initial Commit Assuming This Record is Not Tracked by Javers Yet
javers.commit("Initial", existing);
// Update Logic ...
existing.setUpdatedTimestamp(LocalDateTime.now());
userRepository.save(existing);
}
public void deleteUser(Long id){
User existing = userRepository.findOne(id);
// Initial Commit Assuming This Record is Not Tracked by Javers Yet
javers.commit("Initial", existing);
// Delete Logic ...
userRepository.delete(id);
}
// UserRepository.java
@Repository
@Transactional
@JaversSpringDataAuditable
public interface UserRepository extends JpaRepository<User, Long>{}
使用上述逻辑,您将始终拥有对象在 UPDATE 或 DELETE 发生之前所处的初始状态。在 CREATE 事件中,初始状态将被 Javers 自动捕获。
希望这可以帮助。
如果您询问某种数据迁移工具——JaVers 不提供任何工具。我可以建议只使用 JaVers API,也可以进行批量更改。
虽然可能有点晚了,但我希望这个答案有助于扩展 Bartek 的建议javers.commit()
,因为我遇到了同样的问题,而且解决方案非常简单。
基本上,我创建了一个可以从特定控制器(例如InitialSnapshotJobController
)调用的作业,该控制器公开了一个端点/api/jobs/initialSnapshot
,例如
@GetMapping("/api/jobs/initialSnapshot")
public JobResult initialSnapshotJob(){...}
该作业引用了我想要保留的实体的所有服务,例如
@Autowired
public InitialSnapshotJobController(Javers javers, FileService fileService, PriceService priceService){
initialSnapshot();
}
在工作中我只是findAll()
对每个服务执行一个操作,遍历所有返回的项目,然后手动将它们提交给 JaVers,例如
public void initialSnapshot(){
List<File> files = fileService.findAll();
files.forEach(file ->{
javers.commit("InitialSnapshotJob", file);
})
...
}
这按预期工作,现在我可以将任何未来的更改存储为更新,这允许我只获取从基线更改的内容,而无需为新对象设置 JaVers 标志。
您还可以修改作业以接收服务列表而不是对其进行硬编码,然后如果稍后您需要获取新实体的快照,则可以仅为该实体执行此操作。