Java Hibernate错误将@PostPersist方法中的实体持久化
我在数据库中有一个奇怪的双重插入错误。我有以下课程:Java Hibernate错误将@PostPersist方法中的实体持久化,java,hibernate,jpa,entity,lifecycle,Java,Hibernate,Jpa,Entity,Lifecycle,我在数据库中有一个奇怪的双重插入错误。我有以下课程: TestEntity—具有@PrePersist和@PostPersist方法的实体 审计机构-审计实体 Dataset—DatasetBean的接口 DatasetBean-实现Dataset的无状态bean DatasetFactory-实例Dataset的EJB(查找) 我将问题放在junit测试中(我使用的是嵌入式Glassfish): } 使用DatasetFactory,我尝试在TestEntity的@PostPersist方
- TestEntity—具有@PrePersist和@PostPersist方法的实体
- 审计机构-审计实体
- Dataset—DatasetBean的接口
- DatasetBean-实现Dataset的无状态bean
- DatasetFactory-实例Dataset的EJB(查找)
@PrePersist
public void fillId() {
if (getId() == null || getId() == 0) {
Dataset d = DatasetFactory.createDataset();
Integer i = (Integer) d.fetchJPQLFirstResult("SELECT MAX(te.id) FROM TestEntity te");
if (i == null || i < 100) {
setId(100);
} else {
setId(i + 1);
}
}
}
@PostPersist
public void audit() {
Dataset<Auditing> dataset = DatasetFactory.createDataset();
// dataset.getEntityManager().clear();
Auditing auditing = new Auditing();
auditing.setIdEntidade(String.valueOf(this.getId()));
dataset.insert(auditing);
}
@PrePersist
公共void fillId(){
如果(getId()==null | | getId()==0){
Dataset d=DatasetFactory.createDataset();
整数i=(整数)d.fetchJPQLFirstResult(“从TestEntity te中选择MAX(te.id));
如果(i==null | | i<100){
setId(100);
}否则{
setId(i+1);
}
}
}
@后复印机
公共审计(){
Dataset Dataset=DatasetFactory.createDataset();
//dataset.getEntityManager().clear();
审核=新审核();
auditing.setIdEntidade(String.valueOf(this.getId());
数据集.插入(审计);
}
}
@实体
公共类礼堂实现MyEntity{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私有整数id;
私有字符串标识;
//设置和获取
}
公共接口MyEntity扩展了可序列化{
整数getId();
}我做错了什么?我曾经看到过一个非常类似的问题。。。。你应该-- 小心@PostPersist!HibernateBean持久化或保存操作与数据库插入不同强> 问题可能是您假设@PostPersist方法在插入数据后被调用。。。。然而,情况并非总是如此!PostPersist方法是回调,但它们不是来自数据库的回调!!!正如您所知-hibernate可能没有提交您的事务并完全刷新它。如果您试图使用PostPersist来协调数据库事务之间的障碍,您就犯了错误。 解决方案是在一个适当规划和管理的事务中完成所有插入,并计算出键和级联,以便hibernate能够以正确的方式为您组织插入,或者只是硬编码一个存储过程来为您完成这项工作 我认为您可能正在这里合并有状态和无状态事务逻辑。+1,文档中说“在实体管理器持久化操作实际执行或级联后执行。此调用在数据库插入执行后调用。”它还说“回调方法可能引发RuntimeException。当前事务(如果有的话)必须回滚。”然后它必须在提交事务之前等待回调方法完成。
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager entityManager;
@Override
public void insert(T entidade) {
LOG.info("Inserting: " + entidade);
entityManager.persist(entidade);
}
//...
@PrePersist
public void fillId() {
if (getId() == null || getId() == 0) {
Dataset d = DatasetFactory.createDataset();
Integer i = (Integer) d.fetchJPQLFirstResult("SELECT MAX(te.id) FROM TestEntity te");
if (i == null || i < 100) {
setId(100);
} else {
setId(i + 1);
}
}
}
@PostPersist
public void audit() {
Dataset<Auditing> dataset = DatasetFactory.createDataset();
// dataset.getEntityManager().clear();
Auditing auditing = new Auditing();
auditing.setIdEntidade(String.valueOf(this.getId()));
dataset.insert(auditing);
}