如何无外键和关联实体,用JoinColumn映射OneToMany关系?
解决方案
一、修正@JoinColumn配置(核心解决关联字段映射)
你之前的@JoinColumn参数顺序搞反了,正确配置需要指定子表(child)的关联字段和主表(master_a/master_b)的主键字段,同时禁用外键约束。结合已有的@Where注解,就能生成你需要的查询语句。
正确的MasterA实体配置:
@Table("master_a") class MasterA { @Id private Long id; // 必须添加主键注解,Hibernate依赖主键完成实体映射 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn( name = "master_id", // Child表中存储主实体ID的字段名 referencedColumnName = "id", // MasterA表的主键字段名 foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT) // 禁用数据库外键检查 ) @Where(clause = "type = 'MASTER_A'") // 过滤当前主实体对应的Child类型 private Set<Child> childs; // 省略getter、setter }
MasterB实体仅需修改@Where的type值:
@Table("master_b") class MasterB { @Id private Long id; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn( name = "master_id", referencedColumnName = "id", foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT) ) @Where(clause = "type = 'MASTER_B'") private Set<Child> childs; // 省略getter、setter }
Child实体补充字段注解:
@Table("child") class Child { @Id private Long id; private String type; @Column(name = "master_id") // 若属性名与数据库字段名一致(如masterId对应master_id),可省略此注解 private Long masterId; // 省略getter、setter }
二、关于@DiscriminatorColumn的适用性
@DiscriminatorColumn是单表继承的核心注解,用于父类标记鉴别列以区分不同子类的数据。你的场景是多个主实体共享一个子表,并非继承关系,因此该机制无法反向套用,没必要强行使用。
三、效果验证
配置完成后,Hibernate会自动生成符合需求的查询语句:
select c.* from child c where c.type='MASTER_A' and c.master_id=?
(注:?会被替换为当前MasterA实体的id值)
内容的提问来源于stack exchange,提问作者ECHU
相关产品推荐
相关产品推荐

