Java hibernate中一对一关联的延迟加载问题
我有一个关于延迟加载Java hibernate中一对一关联的延迟加载问题,java,hibernate,lazy-loading,one-to-one,Java,Hibernate,Lazy Loading,One To One,我有一个关于延迟加载OneToOne关联映射的问题 +-----------------+ +------------------+ | USER | | Address | | |1 1| | | ADDRESS_ID +-------------+ | |
OneToOne
关联映射的问题
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
案例1外键位于子表(地址)中
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
在上面的地址中,延迟加载不起作用
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
情况2外键在父表中(用户)
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
在上面的地址中,延迟加载工作
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
有人能解释一下为什么一对一延迟加载在第一种情况下不起作用,但在第二种情况下起作用吗?
@OneToOne
有点棘手
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
这完全取决于您使用的持久性提供程序
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
某些提供程序不尊重FetchType.LAZY
提示
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
您可以尝试指定(在关系的两端)
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
为了了解这里发生了什么,让我们看一下级别:
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
第一种情况:
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| +-------------+ USER_ID (FK) |
| | | |
| | | |
+-----------------+ +------------------+
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
加载时,用户Hibernate必须知道地址是否存在
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
因此Hibernate发出一个类似于以下内容的SQL请求:
SELECT * FROM USER WHERE ID = ?
SELECT * FROM ADDRESS WHERE user_id = ?
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
当获得结果时,实体已经加载,因此没有必要为地址分配LazyProxy。Hibernate分配获取的对象
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
第二种情况:
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
Hibernate不需要检查地址是否存在。这就是创建代理的原因。
@OneToOne
处理起来有点棘手
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
这完全取决于您使用的持久性提供程序
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
某些提供程序不尊重FetchType.LAZY
提示
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
您可以尝试指定(在关系的两端)
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
为了了解这里发生了什么,让我们看一下级别:
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
第一种情况:
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| +-------------+ USER_ID (FK) |
| | | |
| | | |
+-----------------+ +------------------+
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
加载时,用户Hibernate必须知道地址是否存在
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
因此Hibernate发出一个类似于以下内容的SQL请求:
SELECT * FROM USER WHERE ID = ?
SELECT * FROM ADDRESS WHERE user_id = ?
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
当获得结果时,实体已经加载,因此没有必要为地址分配LazyProxy。Hibernate分配获取的对象
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
第二种情况:
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
Hibernate不需要检查地址是否存在。这就是创建代理的原因。阅读本文。它将使您了解为什么反向侧(映射方式)属性上的一对一无法按预期工作
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
实际上,反过来hibernate需要知道映射的值是什么,因为用户可以立即请求值
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
阅读这篇文章,你就会清楚地了解事情是如何运作的
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
感谢阅读本文。它将使您了解为什么反向侧(映射方式)属性上的一对一无法按预期工作
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
实际上,反过来hibernate需要知道映射的值是什么,因为用户可以立即请求值
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
阅读这篇文章,你就会清楚地了解事情是如何运作的
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
谢谢我没能让它工作,所以我使用了一个准备好的语句,在那里我加入了FETCH,无论如何Hibernate在事后查询的东西
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
添加
optional=true
或伪造OneToMany
关系在我看来是错误的解决方法。我一直无法让它工作,所以我使用了一个准备好的语句,其中我JOIN-FETCH
无论如何Hibernate在事后查询的东西
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
添加
optional=true
或伪造OneToMany
关系,依我看,是错误的解决方法。你所说的引号是什么意思:“延迟加载不起作用”?它只意味着在获取用户时,不应获取地址。你所说的引号是什么意思:“延迟加载不起作用”?它只意味着在获取用户时,地址不能取,你能给我解释一下这两种情况的区别吗?你能给我解释一下这两种情况的区别吗?
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?