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

JPA映射看似正常,JUnit测试却抛出JdbcSQLIntegrityConstraintViolationException异常

问题分析与解决方案

核心问题1:JPA映射配置错误导致外键无法写入

在ItemEntity的getCart()方法上,@JoinColumn设置了insertable = false, updatable = false,这会告诉JPA不要在插入或更新ItemEntity时操作cart_id字段。但数据库中cart_id字段是NOT NULL约束,插入时该字段为空,直接触发完整性约束异常。

因为@ManyToOne是双向关联的拥有方(外键存储在ITEM表),必须允许JPA写入外键值,所以这两个属性的设置完全错误。

核心问题2:测试代码中的实体类型与关联设置错误

测试代码里存在明显的实体类型混淆:

  • 创建的是Item item = new Item();,但实际应该使用ItemEntity
  • 调用item.setCompetitionConfigurationSet(cart),但ItemEntity中对应的方法应该是setCart(cart)
    这会导致关联关系没有正确绑定到ItemEntity的cart属性上,进一步加剧外键为空的问题。

具体修复步骤

1. 修正ItemEntity的JPA映射

修改getCart()方法的注解配置,移除insertable和updatable的限制:

@Entity
@Table(name = "ITEM")
@Setter
public class ItemEntity {
    
    //...
    private CartEntity cart;

    public ItemEntity() {}
    
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "cart_id", nullable = false)
    public CartEntity getCart()
    {
        return cart;
    }
}

2. 修正测试代码中的实体与关联设置

确保使用正确的实体类型,并正确维护双向关联:

@Execution(ExecutionMode.CONCURRENT)
@DataJpaTest(showSql = false)
class ItemEntityRepositoryTest
{
    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private ItemEntityRepository repository;
    
    private Long entityId;
        
    @BeforeEach
    void init()
    {
        // 改为使用ItemEntity
        ItemEntity item = new ItemEntity();
        // ... fill other item attributes here
    
        CartEntity cart = new CartEntity();
        // ... fill other cart attribute here

        // 持久化Cart并获取ID
        Long cartId = (Long) entityManager.persistAndGetId(cart);
        cart.setId(cartId);
        
        // 维护双向关联:同时设置Cart的items和Item的cart
        item.setCart(cart);
        cart.setItems(Collections.singletonList(item));

        // 持久化Item
        entityId = (Long) entityManager.persistAndGetId(item);
    }


    @Test
    void findAll_existingItems_returnsAllItems()
    {
        List<ItemEntity> items = repository.findAll();
        assertEquals(1, items.size());
    }
}

额外说明

  • 双向关联中,拥有方(ManyToOne)负责外键的维护,所以必须保证拥有方的@JoinColumn允许插入和更新
  • 持久化时最好同时维护双方的关联关系,避免出现不一致的情况
  • 测试中entityManager.persistAndGetId()会自动将实体纳入持久化上下文,无需手动设置ID(不过手动设置也不会有问题)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:40:44