使用Hibernate单向@ManyToOne映射是否需显式添加关联列?
解决Hibernate单向@ManyToOne映射非主键关联时的插入错误问题
你的问题核心在于单向@ManyToOne关联使用非主键字段,且未显式维护关联外键字段,再加上@JoinColumn设置了insertable = false, updatable = false,导致Hibernate无法生成包含policy_reference_id的插入语句,而数据库要求该字段非空,所以抛出Field 'policy_reference_id' doesn't have a default value错误。
结论:需要在PolicyCatalogEntity中显式添加policyReferenceId字段
下面是具体的解决方案和代码调整:
修改后的PolicyCatalogEntity代码
public class PolicyCatalogEntity extends BaseEntity { // 显式添加外键字段,负责插入/更新时的赋值 @Column(name = "policyReferenceId", nullable = false) private Long policyReferenceId; @ManyToOne(fetch = FetchType.EAGER) // 这里保持insertable和updatable为false,让关联属性仅用于查询关联数据 @JoinColumn(name = "policyReferenceId", referencedColumnName = "policyReferenceId", nullable = false, insertable = false, updatable = false) private PolicyConfigDetailsEntity policyConfigDetailsEntity; @NotBlank private String lobName; // 构造方法、getter/setter省略 }
为什么要这么做?
- 你之前的配置中,关联属性
policyConfigDetailsEntity上的@JoinColumn被设置为insertable=false和updatable=false,意味着Hibernate不会通过这个关联实体来维护policyReferenceId字段的插入和更新操作。 - 显式添加
policyReferenceId字段后,这个字段会直接映射到数据库的policy_reference_id列,你需要在插入PolicyCatalogEntity时手动设置该字段的值,Hibernate会自动把它包含在insert语句中,满足数据库的非空要求。 - 同时,关联的
policyConfigDetailsEntity依然可以通过这个字段查询到对应的关联数据,不影响关联查询的功能。
额外注意事项
- 由于
policyReferenceId不是PolicyConfigDetailsEntity的主键,你需要确保PolicyConfigDetailsEntity中的policyReferenceId字段是唯一的(可以在数据库层面加唯一约束,或者在实体类上添加@Column(unique = true)注解),否则查询关联数据时可能出现匹配多个实体的异常。 - 如果你不想手动维护
policyReferenceId字段,可以去掉@JoinColumn的insertable = false, updatable = false配置,但此时需要确保插入PolicyCatalogEntity时,关联的policyConfigDetailsEntity已经是持久化状态(比如已经存在于数据库中),或者配置cascade属性来级联操作,让Hibernate自动从关联实体中获取policyReferenceId的值。
内容的提问来源于stack exchange,提问作者Utkarsh Yadav
相关产品推荐
相关产品推荐

