如何正确配置JPA实体关联,实现多对多关系下关联数量的存储查询
结论
你必须创建这个中间实体,JPA原生的@ManyToMany仅支持无额外字段的纯关联中间表,一旦需要存储count这类业务字段,就必须把多对多关系拆分为两组一对多关联,中间表对应独立的实体类。
现有代码错误修正
你初步写的CountNodeMachine有两处错误:
@Table注解绑定的表名错误,应该对应你规划的count_machine_node,而不是node_machine- 不要直接声明
machine_id、node_id外键字段,要用关联注解绑定实体,方便后续关联查询
完整关联配置
1. 中间实体CountNodeMachine
@Entity @Table(name = "count_machine_node", uniqueConstraints = { // 增加联合唯一约束,避免同个机器和同个零件重复生成配置记录 @UniqueConstraint(columnNames = {"machine_id", "node_id"}) }) public class CountNodeMachine { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "machine_id", nullable = false) private Machine machine; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "node_id", nullable = false) private NodeMachine nodeMachine; private Integer count; // 按需补充构造方法、getter、setter }
2. 机器实体Machine
删除原有的@ManyToMany关联,改为和中间实体的一对多绑定:
@Entity @Table(name = "machine") public class Machine { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "machine", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) private List<CountNodeMachine> nodeCountList = new ArrayList<>(); }
3. 零部件实体NodeMachine
同样增加和中间实体的一对多绑定:
@Entity @Table(name = "node_machine") public class NodeMachine { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "nodeMachine", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) private List<CountNodeMachine> machineCountList = new ArrayList<>(); }
查询实现
你需要的「通过机器名称和零部件名称查询安装数量」需求,用Spring Data JPA可以直接写查询方法:
public interface CountNodeMachineRepository extends JpaRepository<CountNodeMachine, Long> { Integer findCountByMachineNameAndNodeMachineName(String machineName, String nodeName); }
这套配置完全避免了你担心的冗余问题,同型号轮子只要分别给汽车、摩托车各存一条配置记录即可,不需要重复存储多条零部件记录。
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

