You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.cfg.xml中已正确注册实体类:

    <mapping class="domain.Barrier"/>
    <mapping class="domain.BarrierId"/>
    

    若为Spring环境,需确保@EntityScan注解包含domain包路径。

内容的提问来源于stack exchange,提问作者Michu93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:57:11