Java Hibernate持久化实体能否同时持有关联实体ID和关联实体对象
错误原因
你将数据库account_id字段同时映射给了accountId基础字段和account关联对象,Hibernate默认两个映射都具备该字段的写入权限,因此触发重复映射冲突。
这种需求Hibernate完全支持,不需要删除accountId字段,只需要给其中一个映射标记为只读(禁止插入、更新操作)即可,根据你的使用习惯有两种配置方案:
方案1:以accountId作为写入字段
适合平时赋值习惯直接传入账户ID的场景,给关联对象的@JoinColumn增加只读配置:
@Entity @Table(name = "building") public class Building extends BaseEntity { @Column(name = "name", nullable = false) private String name; @Column(name = "account_id", nullable = false) private Long accountId; // 这里建议把EAGER改成LAZY,只有主动调用getAccount()时才加载关联对象,性能更好 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "account_id", insertable = false, updatable = false) private Account account; // 其余逻辑不变 }
该方案下保存数据时仅需给accountId赋值,account字段会自动关联对应ID的账户实体,需要取ID时直接读取accountId即可,无需触发关联查询。
方案2:以account关联对象作为写入字段
适合平时赋值习惯直接传入账户实体的场景,给accountId字段增加只读配置:
@Entity @Table(name = "building") public class Building extends BaseEntity { @Column(name = "name", nullable = false) private String name; @Column(name = "account_id", nullable = false, insertable = false, updatable = false) private Long accountId; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "account_id") private Account account; // 其余逻辑不变 }
该方案下保存数据时仅需给account赋值,accountId会自动映射数据库存储的账户ID值,直接读取即可,不需要调用account.getId()获取。
注意事项
两种方案都不要同时修改两个字段的值再执行持久化操作,避免出现数据不一致的问题,统一使用你选择的写入字段做更新操作即可。
内容的提问来源于stack exchange,提问作者DrTeeth
相关产品推荐
相关产品推荐

