You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多次调用em.persist()失效:第三次persist操作无法执行

问题分析与解决方案

你的猜测不成立——第三次代码里明确new了全新的QuotaProductInfo实例,不存在共享VO的问题。下面是可能的原因和解决办法:

1. 先确认product2是否触发了执行逻辑

第三次persist被包裹在if(product2!=null)判断中,先排查:

  • product2是否为null,导致代码块根本没执行
  • 如果product2是空字符串,null判断不会拦截,后续Integer.parseInt(qnt2_)可能抛出异常中断执行(若你没收到报错提示,优先确认是否进入了if块)

2. 检查事务提交逻辑

JPA的em.persist()只是将实体托管到持久化上下文,不会立即写入数据库,只有当事务提交或调用em.flush()时,数据才会落库。如果代码执行完没有提交事务,第三次的persist可能仅停留在内存中。

  • 解决:
    • 手动管理事务时,在所有persist操作完成后调用em.getTransaction().commit()
    • 容器管理事务(如Spring环境),确保当前方法被@Transactional注解修饰

3. maxSeq计算存在一致性与并发问题

你通过count(m)+1计算maxSeq的逻辑有明显问题:

  • 第一次persist(quotaInfo)后,事务未提交时,select count(m)可能读不到刚插入的记录(取决于事务隔离级别),导致maxSeq错误
  • 并发场景下,多个请求同时插入会导致quotaSeq重复

正确的做法是直接使用QuotaInfo的主键作为关联值:

em.persist(quotaInfo);
// 如果主键是自增策略,persist后可直接获取(必要时调用em.flush()确保主键生成)
Long maxSeq = quotaInfo.getId(); // 假设QuotaInfo的主键字段是id

4. 检查QuotaProductInfo的实体配置

  • 确认实体的主键生成策略:如果主键是自增,不要手动设置主键值,否则可能导致插入失败
  • 检查字段映射:确保quotaSeq的@Column注解配置正确,没有拼写错误或类型不匹配
  • 查看SQL日志:开启JPA的SQL打印,确认第三次插入的SQL是否执行,是否有约束冲突(如唯一索引重复)

修正后的示例代码

// 手动开启事务(按需)
em.getTransaction().begin();

QuotaInfo quotaInfo = new QuotaInfo();      
quotaInfo.setProject(project);
quotaInfo.setSchool(school);
quotaInfo.setRegion(region);                
quotaInfo.setSalesMan(salesMan);
quotaInfo.setStat(stat);
quotaInfo.setRegDate(LocalDateTime.now());
em.persist(quotaInfo);  
em.flush(); // 确保主键生成
Long maxSeq = quotaInfo.getId();

QuotaProductInfo quotaPInfo_1 = new QuotaProductInfo();     
quotaPInfo_1.setName(product1);
quotaPInfo_1.setQnt(qnt1);
quotaPInfo_1.setPriceUnit(0);
quotaPInfo_1.setQuotaSeq(maxSeq);
em.persist(quotaPInfo_1);               

if(product2 != null && !product2.trim().isEmpty()) {
    QuotaProductInfo quotaPInfo_2 = new QuotaProductInfo();     
    quotaPInfo_2.setName(product2);
    int qnt2 = Integer.parseInt(qnt2_);
    quotaPInfo_2.setQnt(qnt2);
    quotaPInfo_2.setPriceUnit(0);
    quotaPInfo_2.setQuotaSeq(maxSeq);
    em.persist(quotaPInfo_2);   
}

// 提交事务
em.getTransaction().commit();

内容的提问来源于stack exchange,提问作者JayCold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:15:35