Hibernate JPA-尝试创建NamedEntityGraph以避免多次选择(具有OneToOne和OneToMany子级的父级)
我已经停止JPA的实践多年了,现在我正在尝试(使用SpringBoot/Hibernate) 我有以下几点(科特林)Hibernate JPA-尝试创建NamedEntityGraph以避免多次选择(具有OneToOne和OneToMany子级的父级),hibernate,spring-boot,jpa,Hibernate,Spring Boot,Jpa,我已经停止JPA的实践多年了,现在我正在尝试(使用SpringBoot/Hibernate) 我有以下几点(科特林) @NamedEntityGraphs(*[ 姓名识别图( name=“用户角色”, 属性节点=[ 名称三角洲(“名称”), NamedAttributeNode(“用户角色”,子图=“角色属性”)], 子图=[ NamedSubgraph(name=“roleproperties”,attributeNodes=[NamedAttributeNode(“roleType”)])]
@NamedEntityGraphs(*[
姓名识别图(
name=“用户角色”,
属性节点=[
名称三角洲(“名称”),
NamedAttributeNode(“用户角色”,子图=“角色属性”)],
子图=[
NamedSubgraph(name=“roleproperties”,attributeNodes=[NamedAttributeNode(“roleType”)])]
)
])
@实体
@表(name=“[user]”)
类用户实体(
@Id@Column(name=“Id”)
valid:UUID,
val name:String,
val电子邮件:String,
@OneToMany(fetch=FetchType.LAZY)@JoinColumn(name=“user\u id”)
val userRoles:Set,
@OneToOne(fetch=FetchType.LAZY,可选=true)@JoinColumn(name=“id”)
val userProperties:userProperties实体
) { }
...
@实体
@表(name=“user\u role”)
类UserRoleEntity(
@身份证
valid:UUID,
val角色类型:String
)
@实体
@表(name=“用户属性”)
类UserPropertiesEntity(
@身份证
val userId:UUID,
val更新人:UUID?,
val updatedAt:时间戳?,
val属性:字符串?
) {}
...
当使用“用户角色”图进行查询并查看SQL时,将执行2条语句
第一个将user与user_role表连接(这是我所期望的)
然而,第二个查询是用户属性表上的选择。我不明白为什么会有第二个选择。其思想是不需要用户属性表中的任何内容
用户角色图的使用方法如下
val graph = entityManager.getEntityGraph("user-properties")
val properties: MutableMap<String, Any> = HashMap()
properties["javax.persistence.fetchgraph"] = graph
val ue = entityManager.find(UserEntity::class.java, UUID.fromString(id), properties)
val-graph=entityManager.getEntityGraph(“用户属性”)
val属性:MutableMap=HashMap()
属性[“javax.persistence.fetchgraph”]=graph
val ue=entityManager.find(UserEntity::class.java,UUID.fromString(id),属性)
欢迎所有提示
德克萨斯州
Peter需要第二次查询以获取
用户属性
,因为hibernate
需要知道它是否应该为用户属性实体
字段的用户实体
的一对一关系放置null或代理
换句话说,;即使您将关系指定为lazy
,hibernate也无法知道该关系是否为null,或者它应该为相应的userProperties
字段放置一个代理,因此它需要执行第二个查询以获取用户属性。换言之;hibernate无法尊重一对一关系的提取策略FetchType.LAZY
如果你真的想让协会变得真正懒惰,你可以看看下面的内容。谢谢!引用的文章也很有启发性,因此,通过字节码增强和LazyToOne注释,用户_属性上的额外选择消失了。但是,当尝试在一个选择中获取用户和用户_属性的entitygraph时,它失败了。只有select on user表,然后出现异常“org.hibernate.LazyInitializationException:无法执行请求的延迟初始化[com.datylon.gql2.model.UserEntity.userProperties]-没有会话和设置不允许在会话外部加载”
。我想我回到了startI,我没有实体图的经验,也没有实体图是如何工作的。对不起。事实上,我通常更喜欢让一对一
关系保持急切状态,有时使用fetch join直接获取它们,而不是让hibernate进行第二次查询。我希望在实体图方面有更多经验的人能进一步帮助我。
val graph = entityManager.getEntityGraph("user-properties")
val properties: MutableMap<String, Any> = HashMap()
properties["javax.persistence.fetchgraph"] = graph
val ue = entityManager.find(UserEntity::class.java, UUID.fromString(id), properties)