一尘不染

基于“标识”列的“ JPA派生列”值

hibernate

JPA 2.0(Hibernate 4.2.4.Final/Spring 3.2.8.Release)/ Mysql 5.6

对于管理实体E w /自动生成的主键,例如

...
@Id
@GeneratedValue
private int id;

@Column
private String foo;

@Version
@Column(name="mod_date")
private Timetamp modDate;
...

出于传统原因,foo需要等于:{id}:。例如,如果id为204,则foo将为“:204:”,因此在事务中发生这种情况是可行的

em.persist(e);
em.detach(e);
e = em.find(e.getId());
e.setFoo(":" + e.getId() + ":");
...

有没有一种更好的方法来计算值取决于生成的ID的派生列?没有上述技巧,即在持久化之后直接更新列将导致org.hibernate.StaleObjectException。我在单元测试中看到了这种情况(实际上,我可以逐步执行单元测试代码,并且可以复制异常,该异常排除了通常与StaleObjectException关联的多线程问题。


阅读 207

收藏
2020-06-20

共1个答案

一尘不染

您可以使用JPA PostPersist事件监听器来处理。

@Id
@GeneratedValue
private int id;

@Column
private String foo;

@PostPersist
public void onSave(){
    foo = ":" + id + ":";
}

根据JPA 2规范:

在使实体成为持久性或删除实体后,将为该实体调用PostPersist和PostRemove回调方法。这些回调还将在这些操作所级联的所有实体上调用。在数据库插入和删除操作之后,将分别调用PostPersist和PostRemove方法。这些数据库操作可以在调用持久,合并或删除操作之后直接发生,也可以在发生刷新操作后立即发生(可能在事务结束时)。
生成的主键值在PostPersist方法中可用。

2020-06-20