天天看點

JPA 一對一設定無效,連表查詢的時候另外一個實體類的對象值為空

文章目錄

    • 1.前言
    • 2.錯誤示例:
    • 3.正确示例
    • 4.講解

1.前言

今天在使用 JPA 的時候發現了這樣一個問題,User 表和 OrganInfo 表配置了一對一關系,連表查詢的時候隻能夠查到表 User 對象實體的資料,而 OrganInfo 對象實體為空,原因請看下面講解,我設定的是 User 到 OrganInfo 的單項關系,如果想要設定雙向關系,在 OrganInfo 實體類中添加關系即可

2.錯誤示例:

在 User.java中設定對應 OrganInfo 的關系

private static final long serialVersionUID = -1326615142912926353L;
    @Id
    @Column(name = "user_id")
    private String userId;
    @Column(name = "pwd")
    private String pwd;
    @Column(name = "fullname")
    private String fullName;
    @Column(name = "sex")
    private String sex;
    @Column(name = "age")
    private Integer age;
    @Column(name = "tel")
    private String tel;
    @Column(name = "status")
    private Integer status;
    @Column(name = "image_id")
    private String imageId;
    
	// User-OrganInfo
    @OneToOne(fetch = FetchType.EAGER) // EAGER,那麼表示取出這條資料時,它關聯的資料也同時取出放入記憶體中
    @JoinColumn(name = "user_id", referencedColumnName = "user_id",
            insertable = false, updatable = false)
    private OrganInfo organInfo;
	// Get Set 省略
           

OrganInfo 實體類中字段如下(主要看主鍵是誰)

public class OrganInfo implements Serializable {
    private static final long serialVersionUID = -1326615142912926353L;
  
    @Column(name = "user_id", nullable = false)
    private String userId;
    @Id
    @Column(name = "organ_id", nullable = false)
    private String organId;
    @Column(name = "organ_name")
    private String organName;
    @Column(name = "organ_introduce")
    private String organIntroduce;
    @Column(name = "licence_id")
    private String licenceId;
    @Column(name = "image_id")
    private String imageId;
}
           

連表查詢時就會造成空值的現象,如下圖:

JPA 一對一設定無效,連表查詢的時候另外一個實體類的對象值為空

原因是什麼呢?

3.正确示例

修改 OrganInfo 實體類中的主鍵為 userId , 對應資料庫中的主鍵也要修改

public class OrganInfo implements Serializable {
    private static final long serialVersionUID = -1326615142912926353L;
    @Id
    @Column(name = "user_id", nullable = false)
    private String userId;
    @Column(name = "organ_id", nullable = false)
    private String organId;
    @Column(name = "organ_name")
    private String organName;
    @Column(name = "organ_introduce")
    private String organIntroduce;
    @Column(name = "licence_id")
    private String licenceId;
    @Column(name = "image_id")
    private String imageId;
}
           

資料顯示正常

JPA 一對一設定無效,連表查詢的時候另外一個實體類的對象值為空

4.講解

// User-OrganInfo
    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id", referencedColumnName = "user_id",
            insertable = false, updatable = false)
    private OrganInfo organInfo;
           

name: 外鍵字段名稱

referencedColumnName: 參照的主表的主鍵名稱

因為主表要通過主鍵來控制資料的唯一性,而從表也要控制資料的唯一性,才能稱得上為一對一

上面錯誤的例子中,主表通過 userId 來控制資料的唯一性,而從表的外鍵是 userId ,那麼兩個表關聯起來的時候,從表的資料可以不唯一,比如:

主表:userId: 123

從表:organId: zhongShan userId: 123

主表:userId: 123

從表:organId: huanNan userId: 123

(其他資料項省略)

這種就屬于一對多關系了,根本不是一對一

如果将從表的主鍵換為 userId ,也為外鍵,那麼就可以保證從表資料的唯一性,即一對一,如:

主表:userId:123

從表:userId:123 organId: 中山大學

主表:userId:222

從表:userId:222 organId: 華南理工大學

(其他資料項省略)

繼續閱讀