Spring Data Envers Entity 不能为空
Spring Data Envers Entity must not be null
假设我们审计了具有@OneToOne 关系的实体:
@Entity
@Audited
@Table(name = "product")
public class Product {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "active")
private boolean active;
@OneToOne(mappedBy="product", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
private ProductPrice productPrice;
}
@Audited
@Entity
@Table(name = "product_price")
public class ProductPrice {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "amount")
private Long amount;
@OneToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "product_id", nullable = false)
private Product product;
}
并且 RevisionService 具有获取修订和查找更改的方法:
@Transactional
public Page<Revision<Long, Product>> getGroupRevisions(Long productId, int page) {
Page<Revision<Long, Product>> revisions = productRepository.findRevisions(productId, PageRequest.of(page, 5, RevisionSort.desc()));
Long priceId = revisions.getContent().get(0).getEntity().getProductPrice().getId();
Page<Revision<Long, ProductPrice>> priceRevisions = productPriceRepository.findRevisions(priceId, PageRequest.of(page, 5, RevisionSort.desc()));
return revisions;
}
现在,如果我创建新的 Product 和 ProductPrice 记录,然后对 Product 进行 5 次以上的更改(将生成 5 个 RevInfo 记录),我会得到异常:
java.lang.IllegalArgumentException: Entity must not be null!
at org.springframework.util.Assert.notNull(Assert.java:198)
at org.springframework.data.history.AnnotationRevisionMetadata.<init>(AnnotationRevisionMetadata.java:55)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.getRevisionMetadata(EnversRevisionRepositoryImpl.java:237)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.lambda$toRevisions(EnversRevisionRepositoryImpl.java:223)
at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:195)
at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1837)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.toRevisions(EnversRevisionRepositoryImpl.java:226)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.getEntitiesForRevisions(EnversRevisionRepositoryImpl.java:196)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.findRevisions(EnversRevisionRepositoryImpl.java:163)
调试后我看到这个 "null" 实体被 Hibernate 代理并且 Spring Data envers 无法解析此时的修订号:
Number revNo = this.enversService.getRevisionInfoNumberReader().getRevisionNumber(revision);
这里是link到github的测试项目:https://github.com/aquariusmaster/spring-data-envers-bug
所以我的问题是这是 Spring Data Envers 中的错误,还是我在配置中遗漏了什么?
如spring-data-envers team回复,升级boot版本到2.3。1.RELEASE解决问题:
https://github.com/spring-projects/spring-data-envers/issues/34#issuecomment-651681687
假设我们审计了具有@OneToOne 关系的实体:
@Entity
@Audited
@Table(name = "product")
public class Product {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "active")
private boolean active;
@OneToOne(mappedBy="product", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
private ProductPrice productPrice;
}
@Audited
@Entity
@Table(name = "product_price")
public class ProductPrice {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "amount")
private Long amount;
@OneToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "product_id", nullable = false)
private Product product;
}
并且 RevisionService 具有获取修订和查找更改的方法:
@Transactional
public Page<Revision<Long, Product>> getGroupRevisions(Long productId, int page) {
Page<Revision<Long, Product>> revisions = productRepository.findRevisions(productId, PageRequest.of(page, 5, RevisionSort.desc()));
Long priceId = revisions.getContent().get(0).getEntity().getProductPrice().getId();
Page<Revision<Long, ProductPrice>> priceRevisions = productPriceRepository.findRevisions(priceId, PageRequest.of(page, 5, RevisionSort.desc()));
return revisions;
}
现在,如果我创建新的 Product 和 ProductPrice 记录,然后对 Product 进行 5 次以上的更改(将生成 5 个 RevInfo 记录),我会得到异常:
java.lang.IllegalArgumentException: Entity must not be null!
at org.springframework.util.Assert.notNull(Assert.java:198)
at org.springframework.data.history.AnnotationRevisionMetadata.<init>(AnnotationRevisionMetadata.java:55)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.getRevisionMetadata(EnversRevisionRepositoryImpl.java:237)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.lambda$toRevisions(EnversRevisionRepositoryImpl.java:223)
at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:195)
at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1837)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.toRevisions(EnversRevisionRepositoryImpl.java:226)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.getEntitiesForRevisions(EnversRevisionRepositoryImpl.java:196)
at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.findRevisions(EnversRevisionRepositoryImpl.java:163)
调试后我看到这个 "null" 实体被 Hibernate 代理并且 Spring Data envers 无法解析此时的修订号:
Number revNo = this.enversService.getRevisionInfoNumberReader().getRevisionNumber(revision);
这里是link到github的测试项目:https://github.com/aquariusmaster/spring-data-envers-bug
所以我的问题是这是 Spring Data Envers 中的错误,还是我在配置中遗漏了什么?
如spring-data-envers team回复,升级boot版本到2.3。1.RELEASE解决问题: https://github.com/spring-projects/spring-data-envers/issues/34#issuecomment-651681687