在 Spring Boot 中使用 Postload 审核 OneToOne 映射到 Envers 修订
Posted
技术标签:
【中文标题】在 Spring Boot 中使用 Postload 审核 OneToOne 映射到 Envers 修订【英文标题】:Audited OneToOne Mapping to Envers Revision using Postload in Spring Boot 【发布时间】:2021-09-03 20:52:39 【问题描述】:我目前正在尝试在我的 Spring Boot 应用程序中实现版本系统。
客户提交了价值 300 美元的产品订单 -> 现在,如果我的客户将产品订单的价格更改为 350 美元,旧订单仍应显示 300 美元。
经过一些研究,我认为 Hibernate Envers 适合我的用例。
我尝试使用这个例子Mapping to an older revision of an entity with JPA annotations
应该是直截了当的。在创建订单时,我保存 productId 和产品的当前版本。 然后每次 postload 我都会使用 hibernate auditreader 获得适当的修订。
@PersistenceContext
val entityManager: EntityManager? = null;
@Autowired
val sessionFactory: SessionFactory? = null
@Entity
@Table(name="ORDER_TABLE")
@JsonIgnoreProperties(ignoreUnknown = true)
class Order(
var productId:Int?,
var productRevision: Int?,
@OneToOne
var product: Product
) : BaseEntity()
@PostLoad
fun loadProduct()
// val auditReader = AuditReaderFactory.get(entityManager)
val auditReader = AuditReaderFactory.get(sessionFactory?.currentSession)
val query = auditReader.createQuery()
.forEntitiesAtRevision(Product::class.java, product.id)
.add(AuditEntity.id().eq(id))
product = query.singleResult as Product
`
我无法让它工作,因为我无法在 Jpa 实体中获取 entityManager 或 Hibernate Session
这对我的用例是否可行,或者我应该看看不同的东西。
【问题讨论】:
【参考方案1】:如果您要保存订单,则审核是一种不好的管理方式。价格应该是每个订单头寸的价格,并且是该领域的固有部分。价格通常被复制或在折扣的情况下,有时甚至会根据具体情况进行更改。 IMO 你应该明确地对此建模。
【讨论】:
感谢您的回答。我知道创建了另一个名为 OrderProduct 的实体,它与 Product 非常相似,并为每个单独的订单创建了一个新条目。这是更好的方法吗? ` fun createOrder(order: Order) order.orderProduct.id = null order.orderProduct = orderProductRepository.save(order.orderProduct) orderRepository.save(order) ` 我试图找到一种方法来保存整个实体的快照与所有关系也“快照”以拥有所有信息的不可变副本。现在,如果类别发生变化,我需要重复整个过程。 这种方法更适合 IMO,因为该信息通常应该是不可变的。只复制需要不可变的数据。这是您的系统,因此您必须知道是否需要复制类别关联才能理解订单。以上是关于在 Spring Boot 中使用 Postload 审核 OneToOne 映射到 Envers 修订的主要内容,如果未能解决你的问题,请参考以下文章
在 spring-boot 项目中使用 spring mvc xml 项目
Spring boot在Spring boot中Redis的使用
如何在 spring-boot 中禁用 spring-data-mongodb 自动配置
如何在 Spring Boot 中使用 @Transactional 注解