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

PostgreSQL+Hibernate多对多关系:中间表未插入数据求助

问题原因与解决方法

核心问题分析

你的代码存在三个关键问题导致中间表无法写入数据:

1. 多对多关联的维护端未正确维护关系

在@ManyToMany关联中,mappedBy属性标记的是被维护端,真正负责维护中间表关系的是未标记mappedBy的一端(即Produit类)。当前代码仅给Commande设置了商品列表,但未将新创建的Commande添加到每个Produit的commande集合中,Hibernate只会同步维护端的关联变更,因此中间表不会生成关联数据。

2. 错误使用@SecondaryTable注解

Commande类上的@SecondaryTable(name = "produit_commande")属于误用,该注解用于将单个实体的字段拆分到多个数据库表,并非指定多对多关联的中间表。多对多的中间表需要在维护端通过@JoinTable注解配置。

3. 事务未提交

addCommande方法仅开启了事务,但未执行transaction.commit()。虽然session.save会触发临时数据刷新,但未提交的事务最终会回滚,导致关联关系无法持久化到数据库。


具体修复步骤

步骤1:修正多对多关联注解

修改Produit类的@ManyToMany注解,明确中间表配置:

@Entity
@Table(name="produits")
public class Produit {
    // ...其他属性
    
    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(
        name = "product_order", // 匹配数据库中的中间表名称
        joinColumns = @JoinColumn(name = "id_produit"), // 当前实体在中间表的外键
        inverseJoinColumns = @JoinColumn(name = "id_commande") // 关联实体在中间表的外键
    )
    private List<Commande> commande = new ArrayList<>(); // 初始化集合避免空指针

    // ...getter/setter方法
}

修改Commande类,移除错误注解并简化配置:

@Entity
@Table(name="commandes")
// 移除错误的@SecondaryTable注解
public class Commande {
    // ...其他属性
    
    @ManyToMany(mappedBy = "commande", fetch=FetchType.EAGER)
    // 移除不必要的targetEntity和cascade(维护端已配置cascade规则)
    private List<Produit> listProduit = new ArrayList<>(); // 初始化集合

    // ...getter/setter方法
}

步骤2:双向维护关联关系

创建订单时,不仅要给Commande设置商品列表,还要将该订单添加到每个商品的订单集合中:

public static void addCommande(Session session, Transaction transaction,Client client, List<Produit> listProduit){
    
    Commande newCommande = new Commande();
    newCommande.setClient(client);
    newCommande.setListProduit(listProduit);
    
    // 维护双向关联:将当前订单添加到每个商品的commande集合
    for(Produit p : listProduit){
        p.getCommande().add(newCommande);
    }
    
    try {
        transaction = session.beginTransaction();
        session.save(newCommande);
        transaction.commit(); // 提交事务
        System.out.println("La commande a été ajouté avec succès");

    } catch (Exception e) {
        if(transaction != null) transaction.rollback();
       e.printStackTrace();
    }
    finally {
        session.close();
    }
}

步骤3:修复潜在细节问题

  • 所有集合属性在实体类中提前初始化(如new ArrayList<>()),避免空指针异常。
  • ProduitDAO和ClientDAO的查询方法无需传入transaction参数,查询操作默认无需事务支持。

验证修复

运行主类代码后,commandes表会新增订单数据,product_order中间表将生成对应的订单ID与商品ID关联记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:14:56