java - 如何使用 Hibernate Envers 检索具有关系 @ManyToOne 的审计寄存器

标签 java hibernate hibernate-envers

我对使用 Hibernate Envers 和我的类(class)有疑问。

我有一个类 Loja

@Entity
@Audited
@GenericGenerator(name = "Sequence_Generic", strategy = "com.paradigma.ecred.dao.hibernate.generator.ManualGenerator") // sequence generic criado para a atividade 510
@SelectBeforeUpdate @DynamicUpdate
public class Loja extends Persistent {

    @Trim
    @NotBlank(message = "O preenchimento do campo \"CNPJ\" é obrigatório.") 
    @CNPJ(message = "O \"CNPJ da loja\" é inválido")
    private String cnpj;

    @Trim
    @NotBlank(message = "O preenchimento do campo \"Razão social\" é obrigatório.")
    @Size(max = 255, message = "A Razão social deve conter no máximo {max} caracteres.")
    private String razaoSocial;

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="idlojamaster", referencedColumnName = "id", columnDefinition="integer")   
    private Loja lojaMaster;

    @ManyToOne
    @JoinColumn(name="idseguradora", referencedColumnName = "id", columnDefinition="integer")   
    private Seguradora seguradora;

    @ManyToOne
    @JoinColumn(name="idTabelaSeguro", referencedColumnName = "id", columnDefinition="integer") 
    private TabelaSeguro tabelaSeguro;

    // getter e setter
}

我想知道审计字段lojaMasterseguradoratabelaSeguro。这些类用 @Audited 标记。当我进行类似insertedit 的操作时,Id 值区域存储在loja_aud 表中。但是,当我在 Eclipse com.sun.jdi.InvocationException 中调试时,当我以我收到此消息的形式检索这些值时。

它通过Hibernate执行sql,但是类仍然是null,而且我在这些类中找到了一个方法,handler。它包含我的对象的 id

我正在尝试查找信息,但这非常困难。

所以有人可以帮助我!

最佳答案

我找到了一种可以解决您的问题的方法。

我正在调试我的代码,并在这些实体 lojaMasterseguradoratabelaSeguro 中发现了一个名为 handler 的方法。我的问题是,该系统是在较旧的数据库中开发的。所以 Envers 不会在他们的 aud 表 中找到这些实体,也没有找到。

在这张图片中,您可以看到,处理程序是一个代理对象,并且具有对象id

Eclipse Debug

所以我开始尝试寻找一种方法来获取这个Id。因此,当我了解到这是一个代理对象时,我在 Google 中找到了解决方案 Hibernate , 而 Hibernate 将其作为一种策略来获取对象的所有内容。

所以我得到了代码,并得到了 id。

public Serializable getIdentifier(Object object) {

    if (!(object instanceof HibernateProxy) || Hibernate.isInitialized(object)) {
        return ((Persistent)object).getId();
    }

    HibernateProxy proxy = (HibernateProxy) object;
    LazyInitializer initializer = proxy.getHibernateLazyInitializer();
    return initializer.getIdentifier();
}

所以我得到并检查我​​的实体 Id 是否为 null。我得到了 id,findById 得到了 object。我创建了一个 hashmap 来避免每次访问 database 因为 ids 可以重复。

原来这些方法是这样的

@Override
public List<Pojo> getLog(Pojo pojo) {

    Map<Long, Loja> mapLoja = new HashMap<>();
    Map<Long, Seguradora> mapSeguradora = new HashMap<>();
    Map<Long, TabelaSeguro> mapTabelaSeguro = new HashMap<>();

    List<Pojo> auditedList = super.getLog(pojo);

    if (!NullUtil.isNull(auditedList)) {

        for (Pojo pojoAudited : auditedList) {

            Long id = null;

            if (NullUtil.isNull(pojoAudited.getLojaMaster().getId())) {

                id = (Long) this.getIdentifier(pojoAudited.getLojaMaster());
                this.getLojaRegister(mapLoja, id);
                pojoAudited.setLojaMaster(mapLoja.get(id));
            }

            if (NullUtil.isNull(pojoAudited.getSeguradora().getId())) {

                id = (Long) this.getIdentifier(pojoAudited.getSeguradora());
                this.getSeguradoraRegister(mapSeguradora, id);
                pojoAudited.setSeguradora(mapSeguradora.get(id));
            }

            if (NullUtil.isNull(pojoAudited.getTabelaSeguro().getId())) {

                id = (Long) this.getIdentifier(pojoAudited.getTabelaSeguro());
                this.getTabelaSeguroRegister(mapTabelaSeguro, id);
                pojoAudited.setTabelaSeguro(mapTabelaSeguro.get(id));
            }

        }
    }

    return auditedList;
}

private void getLojaRegister(Map<Long, Loja> mapLoja, Long id) {

    if (!mapLoja.containsKey(id)) {
        Loja loja = this.findById(id);
        mapLoja.put(id, loja);
    }
}

private void getSeguradoraRegister(Map<Long, Seguradora> mapSeguradora, Long id) {

    if (!mapSeguradora.containsKey(id)) {
        Seguradora seguradora = this.getSeguradoraService().findById(id);
        mapSeguradora.put(id, seguradora);
    }
}

private void getTabelaSeguroRegister(Map<Long, TabelaSeguro> mapTabelaSeguro, Long id) {

    if (!mapTabelaSeguro.containsKey(id)) {
        TabelaSeguro tabelaSeguro = this.getTabelaSeguroService().findById(id);
        mapTabelaSeguro.put(id, tabelaSeguro);
    }
}

我希望这可以帮助遇到有关 Envers 和旧数据库问题的人。

关于java - 如何使用 Hibernate Envers 检索具有关系 @ManyToOne 的审计寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22896124/

相关文章:

java - Hibernate Envers - 选择 "all"更改实体 ID

java - 在 Hibernate Envers 中是否可以查询给定修订的所有实体?

java - 使用 xuggler 设置 mp3 比特率

java - 没有设备的 Android 应用程序开发

java - 使用值构造函数生成 JAXB 类时出现问题

hibernate - 级联仅删除grails中的事务表

Java: stub 和骨架之间的区别

java - 使用实体监听器测量数据库操作所花费的时间

java - 如何从 Log4j 中过滤特定的异常?

java - Envers AuditReader 阅读器失败