我对使用 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
}
我想知道审计字段lojaMaster
、seguradora
、tabelaSeguro
。这些类用 @Audited
标记。当我进行类似insert
或edit
的操作时,Id
值区域存储在loja_aud
表中。但是,当我在 Eclipse
com.sun.jdi.InvocationException
中调试时,当我以我收到此消息的形式检索这些值时。
它通过Hibernate执行sql,但是类仍然是null,而且我在这些类中找到了一个方法,handler
。它包含我的对象的 id
。
我正在尝试查找信息,但这非常困难。
所以有人可以帮助我!
最佳答案
我找到了一种可以解决您的问题的方法。
我正在调试我的代码,并在这些实体 lojaMaster
、seguradora
和 tabelaSeguro
中发现了一个名为 handler 的方法。我的问题是,该系统是在较旧的数据库中开发的。所以 Envers
不会在他们的 aud 表
中找到这些实体,也没有找到。
在这张图片中,您可以看到,处理程序是一个代理对象
,并且具有对象
的id
。
所以我开始尝试寻找一种方法来获取这个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/