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

Hibernate一对多双向关联中外键字段值为空问题

Hibernate一对多双向关联外键为空问题解决

问题现象

在Hibernate一对多双向关联场景下,执行数据保存操作后,账户表(对应AccountType实体)的外键customerID字段值为空,但客户表(对应Customer实体)已成功插入数据。

相关代码

AccountType实体类

@Entity
public class AccountType {
    
    @Id
    @GeneratedValue
    private int id;
    
    private String type;
    
    private int accountNo;
    
    @ManyToOne
    @JoinColumn(name="customerID")
    private Customer customer;

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public AccountType() {
        super();
    }

    public AccountType(int id, String type, int accountNo) {
        super();
        this.id = id;
        this.type = type;
        this.accountNo = accountNo;
    }

    // getters & setters
}

Customer实体类(一个客户对应多个账户)

@Entity
public class Customer {
    
    @Id
    @GeneratedValue
    private int customerID;
    
    private String customerName;
    
    @OneToMany(mappedBy ="customer" )
    private List<AccountType> accountType;

    public Customer() {
        super();
    }

    // getters & setters
}

主类执行代码

public static void main(String[] args) {
        
        SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
        Session session = factory.getCurrentSession();
        
        Customer customer = new Customer();
        customer.setCustomerName("Pooja kadu");
        
        AccountType accountTypeSaving = new AccountType();
        accountTypeSaving.setType("saving account");
        accountTypeSaving.setAccountNo(12345);
        
        AccountType accountTypeCurrent = new AccountType();
        accountTypeCurrent.setType("Current account");
        accountTypeCurrent.setAccountNo(1235);
        
        List<AccountType> list = new ArrayList<AccountType>(); 
        list.add(accountTypeSaving);
        list.add(accountTypeCurrent);
        
        customer.setAccountType(list);
        
        session.beginTransaction();
        
        session.save(accountTypeCurrent);
        session.save(accountTypeSaving);
        session.save(customer);
        
        session.getTransaction().commit();
    }

问题原因

在双向一对多关联中,@OneToMany注解的mappedBy="customer"指定了关联关系由多的一方(AccountType)维护。但当前代码仅维护了Customer到AccountType的单向关联(将账户列表设置给客户),并未给每个AccountType对象设置对应的Customer引用,导致Hibernate无法识别账户与客户的关联关系,因此不会填充外键customerID的值。

解决办法

方法一:手动维护双向关联(推荐)

在保存数据前,给每个AccountType对象设置对应的Customer引用,确保双向关联关系完整:

// 在设置customer的accountType列表后添加以下代码
accountTypeSaving.setCustomer(customer);
accountTypeCurrent.setCustomer(customer);

修改后的主类核心代码片段:

List<AccountType> list = new ArrayList<AccountType>(); 
list.add(accountTypeSaving);
list.add(accountTypeCurrent);

customer.setAccountType(list);
// 新增双向关联设置
accountTypeSaving.setCustomer(customer);
accountTypeCurrent.setCustomer(customer);

session.beginTransaction();
session.save(accountTypeCurrent);
session.save(accountTypeSaving);
session.save(customer);

方法二:添加级联操作简化保存流程

如果希望通过保存Customer自动保存关联的AccountType,可以修改Customer的@OneToMany注解添加级联配置,但仍需维护双向关联:

@OneToMany(mappedBy ="customer", cascade = CascadeType.ALL)
private List<AccountType> accountType;

此时主类中只需保存Customer即可,但仍需给AccountType设置Customer引用:

// 维护双向关联
accountTypeSaving.setCustomer(customer);
accountTypeCurrent.setCustomer(customer);
customer.setAccountType(list);

session.beginTransaction();
session.save(customer); // 级联保存所有关联的AccountType
session.getTransaction().commit();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:01:04