迁移至Hibernate 6.0.2.Final后通用Id字段未被识别问题求助
解决方案
问题根源
Hibernate 6.0+ 严格区分了 @MappedSuperclass 和 @Inheritance 的用途:@MappedSuperclass 仅用于字段复用(父类不是实体,无对应数据库表),@Inheritance 是实体类之间的继承策略(父类必须是实体),二者不能同时标注在同一个类上,这是你收到警告的核心原因。
具体修改步骤
1. 修正父类注解与方法
移除父类的 @Inheritance 注解,仅保留 @MappedSuperclass,并在抽象 getId() 方法上添加 @Transient 标记(告知Hibernate该属性不映射到数据库列,但可在JPQL中访问):
@MappedSuperclass public abstract class Entity implements Serializable { @Getter @Setter @Column(name = "USER_CREATION", insertable = true, updatable = false) private String auditUtilisateurCreation; // 其他通用字段... @Transient public abstract Object getId(); // 其他通用方法... }
2. 修正子类的getId()返回类型(笔误修复)
子类中 getId() 的返回类型需与 @IdClass 对应,你原代码中写的 ParamCodeLibelleId 应为 ParamCodesId:
@Entity @Table(name = "PARAM_CODES") @IdClass(ParamCodesId.class) @Data public class ParamCodes extends Entity { @Id @Column(name = "FIELD") private String field; @Id @Column(name = "CODE") private String code; @Column(name = "ORDER") private Long order; // 其他字段... @Override public ParamCodesId getId() { return new ParamCodesId(field, code); } }
3. 保留原有JPQL查询
你的查询代码无需修改,Hibernate会自动识别 e.id 为 getId() 方法返回的 ParamCodesId 实例,并正确处理 IN 查询:
@Repository public class JpaParamCodeLibelleRepository { // ... @Transactional(propagation = Propagation.MANDATORY) public List<ParamCodes> getExisingEntity(List<ParamCodesId> ids) { Query querySelect = getEntityManager().createQuery("SELECT e FROM ParamCodes e WHERE e.id in (:ids)", ParamCodes.class); return querySelect.setParameter("ids", ids).getResultList(); } }
效果说明
- 父类的通用字段(如
USER_CREATION)会通过@MappedSuperclass被子类继承,正常映射到数据库表。 @Transient标记的getId()方法不会被Hibernate视为持久化字段,但JPQL可以正常访问该属性,结合@IdClass实现复合主键的统一查询。
内容的提问来源于stack exchange,提问作者Xiidref
相关产品推荐
相关产品推荐

