【问题标题】:How to retrieve audited register with relationship @ManyToOne using Hibernate Envers如何使用 Hibernate Envers 检索具有关系 @ManyToOne 的审核寄存器
【发布时间】:2014-04-06 15:38:16
【问题描述】:

我对使用 Hibernate Envers 和我的班级感到怀疑。

我有一堂课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 表中。但是当我以表格形式检索这些值时,我在Eclipsecom.sun.jdi.InvocationException 中调试时收到了这条消息。

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

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

所以有人可以帮助我!

【问题讨论】:

    标签: java hibernate hibernate-envers


    【解决方案1】:

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

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

    在这张图片中你可以看到,处理程序是一个proxy object,并且拥有objectid

    所以我开始尝试找到一种方法来获取这个Id。所以当我知道这是一个 proxy object 时,我在 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 和旧数据库问题的人。

    【讨论】:

      【解决方案2】:

      我有同样的问题,在我的情况下,我开始对已填充的数据库进行审计。当我使用空数据库时,一切正常。我从this获取信息

      【讨论】:

      • 是的,在 lojamaster_aud 和 seguradora 的数据库中不是空的,但在 tabelaseguro_aud 中是空的。我看到有人建议用旧数据填充表 aud,比如插入。你这样做了吗?
      • 不抱歉:(。我处于早期开发状态,我的数据库中只有测试数据,所以我决定从一个空数据库开始以避免这些问题。
      • 就像在 hibernate 参考中所说,我在 hibernate.cfg.xml 中添加了 AuditEventListener,并且在持久类和我的 @ManyToOne 引用的实体类 (docs.jboss.org/hibernate/envers/3.6/reference/en-US/html_single) 上添加了 @Audited 注释.
      猜你喜欢
      • 2023-02-03
      • 1970-01-01
      • 2013-02-08
      • 1970-01-01
      • 2015-01-21
      • 2019-07-27
      • 2021-11-14
      • 1970-01-01
      • 2013-02-26
      相关资源
      最近更新 更多