【问题标题】:Spring Hibernate Envers: Capture entity being modifiedSpring Hibernate Envers:捕获正在修改的实体
【发布时间】:2020-02-27 15:24:03
【问题描述】:

是否可以在 CustomEntityTrackingListener 或 CustomRevisionListener 中捕获正在修改的实体(书籍)?

我试图获取通过 api /saveBook 或 /update/{id}/{pages} 传递的所有信息,而不仅仅是修订信息。

在envers中审计实体时,它会自动为每个实体创建一个_AUD表和一个修订表以连接实体及其_AUD表

使用自定义修订侦听器我只能获取有关修订的信息,但我想访问正在修改和保存的实体本身。

...
    @PostMapping("/saveBook")
    public Book saveBook(@RequestBody Book book) {
        return repository.save(book);
    }

    @PutMapping("/update/{id}/{pages}")
    public Book updateBook(@PathVariable int id, @PathVariable int pages) {
        Book book = repository.findById(id).get();
        book.setPages(pages);
        return repository.save(book);
    }
...
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Audited
public class Book {

    @Id
    @GeneratedValue
    private int id;

    private String name;

    private int pages;
}

@Entity
//@RevisionEntity(ExampleListener.class)
@RevisionEntity(CustomEntityTrackingRevisionListener.class)
public class ExampleRevEntity extends DefaultRevisionEntity {


    private String username;


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @OneToMany(mappedBy="revision", cascade={CascadeType.PERSIST, CascadeType.REMOVE})
    private Set<ModifiedEntityTypeEntity> modifiedEntityTypes =
            new HashSet<ModifiedEntityTypeEntity>();

}



public class ExampleListener implements RevisionListener {

    @Override
    public void newRevision(Object revisionEntity) {
        ExampleRevEntity exampleRevEntity = (ExampleRevEntity) revisionEntity;
        //Identity identity = (Identity) Component.getInstance("org.jboss.seam.security.identity");

        exampleRevEntity.setUsername("Joaquin");
    }
}
public class CustomEntityTrackingRevisionListener implements EntityTrackingRevisionListener {
    @Override
    public void entityChanged(Class entityClass, String entityName,
                              Serializable entityId, RevisionType revisionType,
                              Object revisionEntity) {

        String type = entityClass.getName();
        //((CustomTrackingRevisionEntity)revisionEntity).addModifiedEntityType(type);
        ((ExampleRevEntity)revisionEntity).addModifiedEntityType(type);
    }

    @Override
    public void newRevision(Object revisionEntity) {

    }

}

【问题讨论】:

    标签: java spring spring-boot hibernate-envers


    【解决方案1】:

    EntityTrackingRevisionListener.entityChanged() 在对象持久化之后执行,因此您可以使用提供的标识符和实体类通过EntityManagerfind() 方法从持久化上下文中获取它。

    【讨论】:

      【解决方案2】:

      有几种方法可以实现这一点。

      • 介绍你自己的事件监听器
      • 使用像 Debezium 这样的 CDC(变更数据捕获)技术。

      在第一种方法中,您可能希望遵循 Envers 文档中关于如何进行条件审计的建议,并引入自定义事件侦听器来扩展 Envers 侦听器,以推断更改并执行您需要的任何任务。

      这可能是一个非常令人生畏和乏味的步骤,因为您必须了解 Hibernate 如何在事件中发出其数据,如何解决差异等。

      我相信这里更简单的方法是使用诸如 Debezium 之类的工具,它使您能够设置一个作业来监控配置数量的表,在您的用例中是特定的 _AUD 感兴趣的表。每次 Envers 插入这些表时,Debezium 都会通过生成一个事件来对插入做出反应,然后您可以对这些事件做出异步反应。

      Debezium 有多种使用方式,包括嵌入到可能适合您的用例的应用程序中,或者嵌入到独立于应用程序并为事件捕获和分派提供冗余和容错的 Kafka Connect 实例中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-20
        • 2018-04-16
        • 1970-01-01
        • 2019-03-01
        • 2021-04-06
        • 2017-11-28
        相关资源
        最近更新 更多