Problem of Hibernate Envers with class objects within a class

-1

I have the following class.

@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
}

Along with these 3 fields, lojaMaster , seguradora , tabelaSeguro . Which are related to itself and other tables. These other tables have their audit tables and their classes are marked with @audited.

But when I debug the code and click on one of these attributes, it shows me the following message in Eclipse.

  

com.sun.jdi.InvocationException

And they are null . Strange that when I perform some operation on this table it writes to the aud table, the records usually, like the ids of those table.

Am I doing something wrong? How do I proceed to be able to audit this table?

    
asked by anonymous 05.04.2014 / 14:13

1 answer

0

I got what you need from the following fact, the database that Envers is working on already has older records. So when Envers checked it did not find a particular object because it did not find it in the audit.

When I execute debug in the code I checked that within the attributes of the Store class, such as lojaMaster , seguradora and tabelaSeguro below can check in the following figure, inside one of these objects I found an attribute or method strange to him, that would be calling handler . I started to search and verified that this method has to do with the fact that this object is proxy for its relationship, since Hibernate only brings the data when required, fact that when occurred, as already said above, did not happen correctly by not finding the record in the table.

But seeing the contents of handler , I saw that it would have a id attribute, that's exactly what I needed, so that I could make a workaround that would be to search the registry for the bank.

Anyway, I started searching for the id of a proxy. I found the solution in forum that would be this method.

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();
}

It returns me the id of the object.

Then I search for id , but not to be accessing the bank at all times I proposed to make a code where I fill a map with id and the object to be located.

Below is the method.

@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);
    }
}

At last, I achieved my goal. I hope this can help people with the same problem as me. Thanks

    
13.04.2014 / 15:59