Jpa中 @OneToOne 懒加载失效的问题
说明一下关系。user
和 user_seting
, 是一个一对一的关系。一个用户记录,关联了一条相关的设置记录。(设置字段太多了,单独列张表出来)。关联列是由 user_seting
在维护,它包含了一个 user_id
字段。
现在的问题就是,根据id检索User
的时候,User
中的 UserSeting
不会懒加载。会立即发出一条检索语句。
实体类
@Entity
@Table(name = "user")
public class User implements Serializable {
private static final long serialVersionUID = 8175166175439387541L;
@Id
@Column(columnDefinition = "INT(11) UNSIGNED COMMENT '用户id'")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(columnDefinition = "varchar(20) COMMENT '昵称'")
private String name;
// 设置
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id", referencedColumnName = "user_id",
foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private UserSeting userSeting;
}
@Entity
@Table(name = "user_seting")
public class UserSeting implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1007318207008996614L;
@Id
@Column(columnDefinition = "INT(11) unsigned COMMENT '设置id'")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(columnDefinition = "TINYINT(1) unsigned COMMENT '是否接受通知'")
private Boolean notify;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", referencedColumnName = "id", unique = true, nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private User user;
}
表
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',
`gender` tinyint(1) unsigned NOT NULL COMMENT '性别。0:女,1:男',
`name` varchar(20) DEFAULT NULL COMMENT '昵称',
`version` int(11) unsigned NOT NULL COMMENT '版本号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `user_seting` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '设置id',
`notify` tinyint(1) unsigned DEFAULT NULL COMMENT '是否接受通知',
`user_id` int(11) unsigned NOT NULL COMMENT '用户id',
PRIMARY KEY (`id`),
UNIQUE KEY `UK_rdchrax5rp1m1y4kpax285krw` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
根据id检索UserSeting
测试代码
@Test
@Transactional
@Rollback(false)
public void jpaTest () {
UserSeting userSeting = this.userSetingService.getOne(1);
System.out.println(userSeting.getNotify());
}
执行了一次查询
正常
SELECT
userseting0_.id AS id1_4_0_,
userseting0_.notify AS notify2_4_0_,
userseting0_.user_id AS user_id3_4_0_
FROM
user_seting userseting0_
WHERE
userseting0_.id =?
根据id检索User
测试代码
@Test
@Transactional
@Rollback(false)
public void jpaTest () {
this.userRepository.findById(1).get();
}
执行了两次查询
第一次查询,正常。
第二次查询就比较诡异,明明设置了 fetch = FetchType.LAZY
,并且也没操作到 userSeting
属性。居然立即发出了一条检索语句。
而且WHERE
条件并不是根据关联字段 user_id
,而是它的主键id
。
SELECT
user0_.id AS id1_2_0_,
user0_.gender AS gender2_2_0_,
user0_.NAME AS name3_2_0_,
user0_.version AS version4_2_0_
FROM
USER user0_
WHERE
user0_.id =?
---------------------------------------------------------------
SELECT
userseting0_.id AS id1_4_0_,
userseting0_.notify AS notify2_4_0_,
userseting0_.user_id AS user_id3_4_0_
FROM
user_seting userseting0_
WHERE
userseting0_.id =?