重复持久化同一实体时抛出PersistenceException而非EntityExistsException的原因
问题:重复持久化实体未抛出预期的EntityExistsException
环境信息
- 项目类型:基于NetBeans Web Application模板的Java Web项目
- 部署容器:Payara 6.2025.7
- 数据库:H2(配置为JTA数据源)
代码实现
REST资源代码
@GET @Path("throwme") @Transactional public Response exceptional(){ E e = new E(); e.setId("yolo"); em.persist(e); return Response .ok("you can't see me twice!") .build(); }
实体类E的定义
@Entity @Data public class E { @Id @GeneratedValue private String id; private int desyncer; }
注:@Data注解来自Lombok
预期与实际结果
- 预期行为:第二次请求
/throwme资源时,抛出EntityExistsException - 实际异常:抛出
jakarta.persistence.PersistenceException,内部嵌套约束违反异常,具体信息如下:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 4.0.1.payara-p4.v202504221851): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.PRIMARY_KEY_45 ON PUBLIC.E(ID) VALUES ( /* 25 */ 'yolo' )"; SQL statement:
排查更新
修改代码添加手动flush操作以定位异常时机:
@GET @Path("throwme") @Transactional public Response exceptional(){ try{ E e = new E(); e.setId("yolo"); em.persist(e); em.flush(); }catch(Exception e){ System.out.println(e.getClass()); } return Response .ok("you can't see me!") .build(); }
排查确认:根异常为jakarta.persistence.PersistenceException,且在调用em.flush()时触发。
内容的提问来源于stack exchange,提问作者zajer
相关产品推荐
相关产品推荐

