I´m doubt about using Hibernate Envers
and my class.
I have a 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
}
I want to know to audit the fields lojaMaster
, seguradora
, tabelaSeguro
. These classes are marked with @Audited
. When I make a operation like insert
or edit
, the Id
values area stored in the loja_aud
table. But when I retrive these values to shoe in the form I got this message when debugging in Eclipse
com.sun.jdi.InvocationException
.
It executes the sql by Hibernate, but the class are still null, also I found one method inside these classes, handler
. It contains the id
of my object.
I´m trying to find informations but it´s very dificult.
So someone can help me!
I found one way to deal with my problem that can be yours.
I was debugin my code, and found inside in these entities lojaMaster
, seguradora
and tabelaSeguro
one method called handler. My problem is, the system is been developed in a older database. So Envers
would not find these entities in their aud table
, and didn´t find.
In this picture you can see, the handler is a proxy object
and has the id
of the object
.
So I started to try to find a way to get this Id
. So when I understand this is a proxy object
I found in Google the solution Hibernate, and Hibernate make this like a strategy to no get all content of the object.
So I got the code, and got the 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();
}
So I got and check if my entity Id
is null
. I got the id, and findById
the object
. I created one hashmap
to don´t every time access the database
because ids
can repeat.
So these methods were in this way
@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);
}
}
I hope this can help someone with problem about Envers
and older database.
I have the same issue, and in my case was that I started audit on a filled db. When I use an empty db all works fine. I take the info from this