Hibernate5使用@Embeddable构建SessionFactory时触发空指针异常
Hibernate迁移注解时SessionFactory构建空指针异常排查方案
以下是针对你遇到问题的核心排查点和修复方案:
检查复合主键类
BarrierId的合规性
Hibernate对@Embeddable主键类有强制要求,缺失任何一项都可能导致反射实例化时抛出NPE:- 必须提供公共无参构造器,Hibernate依赖反射创建该类实例,无此构造器会直接触发空指针或反射异常。
- 所有主键属性必须配备getter/setter方法(或设为public),确保Hibernate能正确读写属性值。
- 必须重写
equals()和hashCode()方法,否则Hibernate无法正确识别主键实例的唯一性。
合规的
BarrierId示例:@Embeddable public class BarrierId implements Serializable { // 强制要求的无参构造器 public BarrierId() {} private Long siteId; private String barrierCode; // getter/setter方法 public Long getSiteId() { return siteId; } public void setSiteId(Long siteId) { this.siteId = siteId; } public String getBarrierCode() { return barrierCode; } public void setBarrierCode(String barrierCode) { this.barrierCode = barrierCode; } // 重写equals和hashCode @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; BarrierId barrierId = (BarrierId) o; return Objects.equals(siteId, barrierId.siteId) && Objects.equals(barrierCode, barrierId.barrierCode); } @Override public int hashCode() { return Objects.hash(siteId, barrierCode); } }检查
Barrier实体类的注解配置- 必须添加
@Entity注解,明确标记为Hibernate实体类。 @EmbeddedId字段类型必须是BarrierId,且配备对应的getter/setter方法。- 原XML中的版本字段必须添加
@Version注解,遗漏会导致Hibernate内部版本控制逻辑出错。 - 实体类必须提供公共无参构造器,否则Hibernate无法实例化实体对象。
合规的
Barrier示例:@Entity public class Barrier { // 强制要求的无参构造器 public Barrier() {} @EmbeddedId private BarrierId id; @Version private Integer version; // 其他业务属性 private String barrierName; // getter/setter方法 public BarrierId getId() { return id; } public void setId(BarrierId id) { this.id = id; } public Integer getVersion() { return version; } public void setVersion(Integer version) { this.version = version; } public String getBarrierName() { return barrierName; } public void setBarrierName(String barrierName) { this.barrierName = barrierName; } }- 必须添加
排查注解包导入错误
确保所有JPA注解来自同一规范包:- 旧版Hibernate使用
javax.persistence.* - 新版Hibernate(5.4+)使用
jakarta.persistence.*
禁止混用不同包的注解(如同时用javax.persistence.Embeddable和org.hibernate.annotations.Entity),这会导致Hibernate解析注解时出现异常。
- 旧版Hibernate使用
检查Hibernate配置的实体扫描
确认hibernate.cfg.xml中已正确注册实体类:<mapping class="domain.Barrier"/> <mapping class="domain.BarrierId"/>若为Spring环境,需确保
@EntityScan注解包含domain包路径。
内容的提问来源于stack exchange,提问作者Michu93
相关产品推荐
相关产品推荐

