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

JPA保存含UserRoles的User实体触发ORA-02291约束错误的解决咨询

问题

保存包含UserRoles集合的User实体时,触发外键约束错误:

oracle.jdbc.OracleDatabaseException: ORA-02291: integrity constraint (APP_OWNER.SYS_C009043) violated - parent key not found

其中SYS_C009043是USER_ROLES表中要求userId必须存在于USER表的外键约束。请问能否让JPA在保存User后自动设置UserRoles的userId再保存?还是必须移除级联保存,先保存User,手动设置UserRoles的userId后再保存角色?

现有实体代码

User 实体

import lombok.*;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.List;

@Entity
@Table(name = "USER")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long userId;

    @JoinColumn(name = "userId", referencedColumnName = "userId")
    @OneToMany(cascade=CascadeType.ALL)
    private List<UserRoles> userRoles;

}

UserRoles 实体

import lombok.*;

import javax.persistence.*;

@Entity
@Table(name = "USER_ROLES")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserRoles {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long userRolesId;

    @Column
    private long userId;

    @Column
    private long roleId;

}

解决方案

不需要手动分步保存,修正JPA的关联映射配置后,就能让JPA自动处理外键赋值:

  • 修正User实体的关联注解
    当前@OneToMany配置缺少双向关联映射,且@JoinColumn使用错误。外键字段在USER_ROLES表,应由多的一方维护关联,所以修改@OneToMany配置:

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<UserRoles> userRoles;
    
  • 修改UserRoles实体,添加双向关联
    把原有的userId字段替换为User类型的关联属性,通过@ManyToOne和@JoinColumn指定外键:

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "userId", nullable = false)
    private User user;
    
    // 移除原来的userId字段
    // @Column
    // private long userId;
    
  • 建立对象间的双向关联
    创建User和UserRoles实例时,需要互相绑定关联关系:

    User user = new User();
    UserRoles role = new UserRoles();
    role.setRoleId(1L);
    role.setUser(user); // 绑定关联的User对象
    user.setUserRoles(List.of(role));
    
    userRepository.save(user);
    

完成以上配置后,JPA会自动按顺序执行:先插入User记录生成userId,再将该userId赋值给UserRoles的外键字段,最后插入UserRoles记录,全程无需手动设置userId。

如果坚持保留userId字段而不用对象关联(不推荐,不符合JPA最佳实践),可以在User实体的@OneToMany中添加@MapKeyColumn(name = "userId"),但这种方式需要手动维护关联,远不如对象关联便捷。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:45:46