在hibernate中一对一关联的延迟加载问题

时间:2015-10-09 06:41:51

标签: java hibernate lazy-loading one-to-one

我有一个与延迟加载OneToOne关联映射有关的问题。

案例1 外键位于子表(地址)

@Entity
public class User {
    ..........
    @OneToOne(mappedBy="user")
    private Address address;


@Entity
public class Address{
    .........
    @OneToOne
    @JoinColumn(name = "user_id")
    private User user;

在上面的地址中,延迟加载不起作用。

案例2 外键位于父表(用户)

@Entity
public class User {
    .............
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="address_id")
    private Address address;


@Entity
public class Address {
    ........
    @OneToOne(mappedBy="address")
    private User user;

在上面的地址延迟加载工作。

可以请某人解释一下为什么One to one延迟加载在第一种情况下不起作用但在第二种情况下有效吗?

3 个答案:

答案 0 :(得分:2)

@OneToOne处理起来有点棘手。

这完全取决于您正在使用的持久性提供程序。

有些提供商不尊重FetchType.LAZY提示。

您可以尝试指定(在关系的两端)

@OneToOne(optional = true, fetch = FetchType.LAZY)

要了解此处发生的事情,请查看级别:

第一种情况:

+-----------------+             +------------------+
| USER            |             |  Address         |
|                 |1           1|                  |
|                 +-------------+  USER_ID (FK)    |
|                 |             |                  |
|                 |             |                  |
+-----------------+             +------------------+

加载用户时,Hibernate必须知道地址是否存在。

因此Hibernate发出类似于此的SQL请求:

SELECT * FROM USER WHERE ID = ?
SELECT * FROM ADDRESS WHERE user_id = ?

获取结果时,实体已经加载,因此将LazyProxy分配给Address是没有意义的。 Hibernate分配获取的对象。

第二种情况:

+-----------------+             +------------------+
| USER            |             |  Address         |
|                 |1           1|                  |
| ADDRESS_ID      +-------------+                  |
|                 |             |                  |
|                 |             |                  |
+-----------------+             +------------------+

SELECT * FROM USER WHERE ID = ?

Hibernate不需要检查地址是否存在。这就是创建代理的原因。

答案 1 :(得分:1)

我无法使它工作,所以我最后使用了一个准备好的声明,其中JOIN FETCH Hibernate事后无论如何都要查询的事情。

添加optional=true或伪造OneToMany关系是IMO错误的解决方法。

答案 2 :(得分:0)

阅读这篇文章。它将帮助您理解为什么反向(映射)属性中的一对一不能按预期工作。One to One Lazy explanation

实际上在反面hibernate需要知道映射的价值是什么,因为用户可以立即询问值。

阅读文章,您将清楚地了解事情是如何运作的。

由于