Hibernate Envers 如何正确获取日志历史记录?
Hibernate Envers how to get the log history properly?
我使用 Hibernate Envers 创建了一个 table 审计日志,我使用 Spring Data Envers 作为我的库,当我 save/update/delete 它成功地将日志保存在我的 autid_log table,但是当我想检索日志数据时,出现无限循环错误,我该如何正确执行此操作?这是我的代码:
这是我的控制器:
@GetMapping("/getPartnerRelationshipLog/{partnerId}")
public ResponseEntity<?> getPartnerRelationshipLog(@PathVariable Long partnerId) {
// Long id = partner.getId();
Revisions<Integer,Partner> history = partnerService.findRelationLog(partnerId);
return ResponseEntity.ok(history);
}
这是我的 Partner.java 模型:
包裹 com.example.envers.auditing.Model;
@Data
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "msPartner")
public class Partner {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
public String partnerCode;
public String partnerName;
@CreatedDate
private Date createDate;
@LastModifiedDate
private Date lastModifiedDate;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String modifiedBy;
@OneToMany(mappedBy = "partner", cascade = CascadeType.ALL)
public List<PartnerShipment> partnerShipment;
}
这是我的 PartnerShipment.java :
@Data
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "msPartnerShipment")
public class PartnerShipment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
public String partnerShipmentCode;
public String partnerShipmentAddress;
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "partnerId")
// @NotAudited
public Partner partner;
@CreatedDate
private Date createDate;
@LastModifiedDate
private Date lastModifiedDate;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String modifiedBy;
}
这是我的服务:
public Revisions<Integer,Partner> findRelationLog(Long id) {
Revisions<Integer,Partner> partner = partnerRepository.findRevisions(id);
return partner;
}
这是我的存储库:
@Repository
public interface PartnerRepository extends RevisionRepository<Partner, Long, Integer>, JpaRepository<Partner, Long > {
}
这是我的 Application.java
@SpringBootApplication
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
@EnableJpaAuditing
public class AuditingApplication {
public static void main(String[] args) {
SpringApplication.run(AuditingApplication.class, args);
}
}
当我得到 id = 1 的数据时,我得到了类似循环无限错误的东西,从 java.lang.WhosebugError 开始:null,我在终端中看到的只有这个 :
java.lang.WhosebugError: null
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
我错过了什么来避免这个错误?
在您的两个实体上添加 @EqualsAndHashCode(of = "id")
。我觉得用@ToString
来指定必填字段也不错。希望这能解决您的问题。
@Data
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "msPartner")
@EqualsAndHashCode(of = "id")
@ToString(of = {"id", "partnerCode", "partnerName"})
public class Partner {}
@Data
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "msPartnerShipment")
@EqualsAndHashCode(of = "id")
@ToString(of = {"id", "partnerShipmentCode", "partnerShipmentAddress"})
public class PartnerShipment {}
@Data
注释实现 @EqualsAndHashCode
。但在这种情况下,它正在创建一个无限循环递归。示例:对于 hashCode 方法,@EqualsAndHashCode
的默认实现将包括所有字段。
public class Partner {
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $id = this.getId();
result = result * PRIME + ($id == null ? 43 : $id.hashCode());
final Object $partnerCode = this.getPartnerCode();
result = result * PRIME + ($partnerCode == null ? 43 : $partnerCode.hashCode());
final Object $partnerName = this.getPartnerName();
result = result * PRIME + ($partnerName == null ? 43 : $partnerName.hashCode());
final Object $createDate = this.getCreateDate();
result = result * PRIME + ($createDate == null ? 43 : $createDate.hashCode());
final Object $lastModifiedDate = this.getLastModifiedDate();
result = result * PRIME + ($lastModifiedDate == null ? 43 : $lastModifiedDate.hashCode());
final Object $createdBy = this.getCreatedBy();
result = result * PRIME + ($createdBy == null ? 43 : $createdBy.hashCode());
final Object $modifiedBy = this.getModifiedBy();
result = result * PRIME + ($modifiedBy == null ? 43 : $modifiedBy.hashCode());
final Object $partnerShipment = this.getPartnerShipment();
result = result * PRIME + ($partnerShipment == null ? 43 : $partnerShipment.hashCode());
return result;
}
}
看看partnerShipment
。它使用 result = result * PRIME + ($partnerShipment == null ? 43 : $partnerShipment.hashCode());
并且 partnerShipment
是一个列表。
并且列表的 hashCode
来自 AbstractList
即
public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
在这种情况下,它遍历每个 PartnerShipment
项目并调用它的 hashCode 方法。并且您还在 PartnerShipment
上使用 @Data
注释,因此它的 hashCode 方法还包括 Partner
字段,它创建了一个无限递归。
我使用 Hibernate Envers 创建了一个 table 审计日志,我使用 Spring Data Envers 作为我的库,当我 save/update/delete 它成功地将日志保存在我的 autid_log table,但是当我想检索日志数据时,出现无限循环错误,我该如何正确执行此操作?这是我的代码:
这是我的控制器:
@GetMapping("/getPartnerRelationshipLog/{partnerId}")
public ResponseEntity<?> getPartnerRelationshipLog(@PathVariable Long partnerId) {
// Long id = partner.getId();
Revisions<Integer,Partner> history = partnerService.findRelationLog(partnerId);
return ResponseEntity.ok(history);
}
这是我的 Partner.java 模型: 包裹 com.example.envers.auditing.Model;
@Data
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "msPartner")
public class Partner {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
public String partnerCode;
public String partnerName;
@CreatedDate
private Date createDate;
@LastModifiedDate
private Date lastModifiedDate;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String modifiedBy;
@OneToMany(mappedBy = "partner", cascade = CascadeType.ALL)
public List<PartnerShipment> partnerShipment;
}
这是我的 PartnerShipment.java :
@Data
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "msPartnerShipment")
public class PartnerShipment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
public String partnerShipmentCode;
public String partnerShipmentAddress;
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "partnerId")
// @NotAudited
public Partner partner;
@CreatedDate
private Date createDate;
@LastModifiedDate
private Date lastModifiedDate;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String modifiedBy;
}
这是我的服务:
public Revisions<Integer,Partner> findRelationLog(Long id) {
Revisions<Integer,Partner> partner = partnerRepository.findRevisions(id);
return partner;
}
这是我的存储库:
@Repository
public interface PartnerRepository extends RevisionRepository<Partner, Long, Integer>, JpaRepository<Partner, Long > {
}
这是我的 Application.java
@SpringBootApplication
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
@EnableJpaAuditing
public class AuditingApplication {
public static void main(String[] args) {
SpringApplication.run(AuditingApplication.class, args);
}
}
当我得到 id = 1 的数据时,我得到了类似循环无限错误的东西,从 java.lang.WhosebugError 开始:null,我在终端中看到的只有这个 :
java.lang.WhosebugError: null
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
at com.example.envers.auditing.Model.Partner.hashCode(Partner.java:31) ~[classes/:na]
at com.example.envers.auditing.Model.PartnerShipment.hashCode(PartnerShipment.java:33) ~[classes/:na]
at java.util.AbstractList.hashCode(AbstractList.java:541) ~[na:1.8.0_241]
at org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy.hashCode(CollectionProxy.java:131) ~[hibernate-envers-5.4.17.Final.jar:5.4.17.Final]
我错过了什么来避免这个错误?
在您的两个实体上添加 @EqualsAndHashCode(of = "id")
。我觉得用@ToString
来指定必填字段也不错。希望这能解决您的问题。
@Data
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "msPartner")
@EqualsAndHashCode(of = "id")
@ToString(of = {"id", "partnerCode", "partnerName"})
public class Partner {}
@Data
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "msPartnerShipment")
@EqualsAndHashCode(of = "id")
@ToString(of = {"id", "partnerShipmentCode", "partnerShipmentAddress"})
public class PartnerShipment {}
@Data
注释实现 @EqualsAndHashCode
。但在这种情况下,它正在创建一个无限循环递归。示例:对于 hashCode 方法,@EqualsAndHashCode
的默认实现将包括所有字段。
public class Partner {
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $id = this.getId();
result = result * PRIME + ($id == null ? 43 : $id.hashCode());
final Object $partnerCode = this.getPartnerCode();
result = result * PRIME + ($partnerCode == null ? 43 : $partnerCode.hashCode());
final Object $partnerName = this.getPartnerName();
result = result * PRIME + ($partnerName == null ? 43 : $partnerName.hashCode());
final Object $createDate = this.getCreateDate();
result = result * PRIME + ($createDate == null ? 43 : $createDate.hashCode());
final Object $lastModifiedDate = this.getLastModifiedDate();
result = result * PRIME + ($lastModifiedDate == null ? 43 : $lastModifiedDate.hashCode());
final Object $createdBy = this.getCreatedBy();
result = result * PRIME + ($createdBy == null ? 43 : $createdBy.hashCode());
final Object $modifiedBy = this.getModifiedBy();
result = result * PRIME + ($modifiedBy == null ? 43 : $modifiedBy.hashCode());
final Object $partnerShipment = this.getPartnerShipment();
result = result * PRIME + ($partnerShipment == null ? 43 : $partnerShipment.hashCode());
return result;
}
}
看看partnerShipment
。它使用 result = result * PRIME + ($partnerShipment == null ? 43 : $partnerShipment.hashCode());
并且 partnerShipment
是一个列表。
并且列表的 hashCode
来自 AbstractList
即
public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
在这种情况下,它遍历每个 PartnerShipment
项目并调用它的 hashCode 方法。并且您还在 PartnerShipment
上使用 @Data
注释,因此它的 hashCode 方法还包括 Partner
字段,它创建了一个无限递归。