天天看点

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: 华南理工大学

(其他数据项省略)

继续阅读