[英]Hibernate OneToOne automatic join fetching (resolving n+1 problem)
Hibernate 3.3 有一个 n+1 select 问题。
为简单起见,我将只做一个简短的抽象示例。
假设我们有以下简单的类:
class MainEntity {
@Id
public Long id; //we have a table generator create this id
@OneToOne ( mappedBy ="main" )
public SubEntity subEntity;
}
class SubEntity {
@Id
@Column( name = "mainId" ) //note that this is the same column as the join column below
public Long mainId; //in order to have the exact same id as the corresponding MainEntity
@OneToOne ( fetch = FetchType.LAZY )
@JoinColumn ( name = "mainId", insertable = false, updatable = false, nullable = false )
public MainEntity main; //this is used for navigation and queries (" ... subentity.main = :x")
}
如您所见, SubEntity
与MainEntity
的关系由两个属性表示,其中mainId
属性是负责管理关系/外键的属性。
这工作得很好,完全符合我们的需求。
但是,急切地加载SubEntity
和MainEntity
存在一个问题。
假设我有一个返回MainEntity
集合的查询。 使用当前设置, Hibernate 将发出 n + 1 个选择:查询本身 + n 为每个SubEntity
选择。
当然,我可以在查询中添加join fetch
,但我更希望 Hibernate 自动执行此操作。 因此我尝试添加@Fetch( FetchMode.JOIN )
,但这并没有做任何事情。
使用@Fetch( FetchMode.SUBSELECT )
也没有问题,这应该将 select 语句减少到 2 - 原始查询和子实体的 select (至少这是在另一个用@CollectionOfElements
和@Fetch( FetchMode.SUBSELECT )
注释的属性上发生的情况@Fetch( FetchMode.SUBSELECT )
)。
join fetch or use a single select in order to eagerly load the sub entities?所以问题是:我如何告诉 Hibernate加入 fetch 或使用单个 select 以便急切地加载子实体? 我错过了什么吗?
提前致谢,
托马斯
PS:可能有问题的一件事可能是mappedBy = "main"
没有引用实际的 id 列,但我无法将其更改为mappedBy = "id"
。
如果要在 MainEntity 和 SubEntity 之间共享主键,请使用PrimaryKeyJoinColumn
和MapsId
注释。
通过使用PrimaryKeyJoinColumn
,通过使用相同的主键将MainEntity
表与SubEntity
表连接来加载实体。 它应该可以解决 n+1 个问题。
MapsId
注释要求 Hibernate 从另一个关联实体复制标识符,在我们的示例中,会将SubEntity.mainEntity.id
复制到SubEntity.id
。
@Entity
public class MainEntity {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "main_Id")
private Long id;
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private SubEntity subEntity ;
}
@Entity
public class SubEntity
{
@Id @Column(name="main_Id_FK") Long id;
@MapsId
@OneToOne
@JoinColumn(name = "main_Id_FK")
@PrimaryKeyJoinColumn
private MainEntity mainEntity;
}
Hibernate 参考文档:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.