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

Hibernate双向映射无返回结果,请求技术排查建议

Spring Data JPA查询Users实体无法获取关联映射数据的排查方案

我用Hibernate定义了实体间的双向映射,但通过Spring Data JPA按ID查询Users表数据时,只能获取Users自身的字段,拿不到关联的ProgrammeMemberships和ContactsNumbers数据,请问问题出在哪?

实体类代码

Users类

@Entity
@Table(name = "USERS", schema = "public")
public class Users implements Serializable{

    @Id
    @Column(name = "PERSON_ID")
    private Long personId;

    @Column(name = "EMAIL_VERIFIED")
    private String emailVerified;

    @Column(name = "MOBILE_VERIFIED")
    private String phoneVerified;

    @OneToOne(mappedBy = "people")
    @JsonBackReference
    private ProgrammeMemberships programmeMemberships;

    @OneToMany(mappedBy = "peopleTable")
    @JsonBackReference
    private List<ContactsNumbers> contactsNumbers = new ArrayList<>();

    public List<ContactsNumbers> getContactsNumbers() {
        return contactsNumbers;
    }

    public void setContactsNumbers(List<ContactsNumbers> contactsNumbers) {
        this.contactsNumbers = contactsNumbers;
    }

    public Long getPersonId() {
        return personId;
    }

    public void setPersonId(Long personId) {
        this.personId = personId;
    }

    public String getEmailVerified() {
        return emailVerified;
    }

    public void setEmailVerified(String emailVerified) {
        this.emailVerified = emailVerified;
    }

    public String getPhoneVerified() {
        return phoneVerified;
    }

    public void setPhoneVerified(String phoneVerified) {
        this.phoneVerified = phoneVerified;
    }

    public ProgrammeMemberships getProgrammeMemberships() {
        return programmeMemberships;
    }

    public void setProgrammeMemberships(ProgrammeMemberships programmeMemberships) {
        this.programmeMemberships = programmeMemberships;
    }
}

Members类(存在构造函数名笔误)

@Entity
@Table(name = "MEMBERS", schema = "public")
public class Members implements Serializable {

    @Id
    @Column(name = "MEM_UID")
    private Long memUid;

    @Column(name = "PTS_BAL")
    private Long ptsBal;

    @Column(name = "ACTIVE_STATUS")
    private String activeStatus;

    @Column(name = "CHANGED")
    private Date changed;

    @OneToOne
    @JoinColumn(name = "PER_PERSON_ID")
    @JsonManagedReference
    private People people;


    public ProgrammeMemberships() {
    }

    public ProgrammeMemberships(Long memUid, Long ptsBal, String activeStatus, Date changed) {
        this.memUid = memUid;
        this.ptsBal = ptsBal;
        this.activeStatus = activeStatus;
        this.changed = changed;
    }


    public Long getMemUid() {
        return memUid;
    }

    public void setMemUid(Long memUid) {
        this.memUid = memUid;
    }

    public Long getPtsBal() {
        return ptsBal;
    }

    public void setPtsBal(Long ptsBal) {
        this.ptsBal = ptsBal;
    }

    public String getActiveStatus() {
        return activeStatus;
    }

    public void setActiveStatus(String activeStatus) {
        this.activeStatus = activeStatus;
    }

   public People getPeople() {
        return people;
    }

    public void setPeople(People people) {
        this.people = people;
    }

    public Date getChanged() {
        return changed;
    }

    public void setChanged(Date changed) {
        this.changed = changed;
    }
}

ContactsNumbers类

@Entity
@Table(name = "CONTACT_NUMBERS", schema = "public")
public class ContactsNumbers {

    @Id
    @Column(name = "CONTACT_ID")
    private Long contactId;
    @Column(name = "CONTACT_NO")
    private String contactNo;

    @Column(name = "MOBILE_VERIFIED")
    private String mobileVerified;
    
    @ManyToOne
    @JoinColumn(name = "PER_PERSON_ID")
    @JsonManagedReference
    private People peopleTable;

    @Column(name = "PREFERRED")
    private String preferred;

    public void setContactId(Long contactId) {
        this.contactId = contactId;
    }

    public Long getContactId() {
        return contactId;
    }

    public String getContactNo() {
        return contactNo;
    }

    public void setContactNo(String contactNo) {
        this.contactNo = contactNo;
    }

    public String getMobileVerified() {
        return mobileVerified;
    }

    public void setMobileVerified(String mobileVerified) {
        this.mobileVerified = mobileVerified;
    }

    public String getPreferred() {
        return preferred;
    }

    public void setPreferred(String preferred) {
        this.preferred = preferred;
    }

   public People getPeopleTable() {
        return peopleTable;
    }

    public void setPeopleTable(People peopleTable) {
        this.peopleTable = peopleTable;
    }
}

问题排查方向

  • 懒加载机制导致关联数据未加载:Hibernate默认对关联映射使用懒加载(FetchType.LAZY),调用Spring Data JPA的findById方法时只会查询Users表,不会主动加载关联对象。如果会话关闭后再访问关联属性,会因懒加载初始化失败拿不到数据。可以在关联注解上添加fetch = FetchType.EAGER强制立即加载,或者自定义查询用JOIN FETCH主动加载关联数据。
  • 实体映射关系不匹配:存在多处明显错误:
    1. Users类中@OneToOne(mappedBy = "people")对应的关联实体应为ProgrammeMemberships,但你提供的代码里该实体类名为Members,且关联字段是People类型而非Users类型——存在类名混淆(Users和People是否为同一实体?需统一或修正映射)。
    2. Members类的构造函数名为ProgrammeMemberships,属于笔误,会导致实体初始化异常,直接破坏映射关系。
  • JSON序列化注解的影响:@JsonBackReference会在JSON序列化时忽略该字段,即使实体已加载关联数据,返回的JSON结果中也看不到。若需要返回关联数据,可调整@JsonBackReference和@JsonManagedReference的位置,或改用@JsonIgnoreProperties避免循环引用同时保留序列化。
  • 查询未指定关联加载:默认的findById是单表查询,不会触发关联查询。可在Repository接口中自定义查询方法:
    @Query("SELECT u FROM Users u JOIN FETCH u.programmeMemberships JOIN FETCH u.contactsNumbers WHERE u.personId = :id")
    Users findByIdWithAssociations(@Param("id") Long id);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 12:20:02