Hibernate OneToOne自动抓取连接(解决n+1问题)



我们在Hibernate 3.3中有一个n+1选择问题。

为简单起见,我只做一个简短的抽象示例。

假设我们有以下简单类:

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")
}

因此,您可以看到SubEntityMainEntity的关系由两个属性表示,其中mainId属性负责管理关系/外键。

这工作得很好,完全符合我们的需要。

然而,急切加载SubEntityMainEntity有一个问题。

假设我有一个查询,返回MainEntity的集合。在当前的设置中,Hibernate将发出n + 1个select:查询本身为每个SubEntity + n个select。

当然,我可以在查询中添加join fetch,但我更希望Hibernate自动执行此操作。因此,我尝试添加@Fetch( FetchMode.JOIN ),但这没有做任何事情。

我使用@Fetch( FetchMode.SUBSELECT )也没有问题,它应该将选择语句减少到2 -原始查询和子实体的选择(至少这是在@CollectionOfElements@Fetch( FetchMode.SUBSELECT )注释的另一个属性上发生的事情)。


所以问题是:我如何告诉Hibernate 自动 join fetch或使用单个select来急切加载子实体?我错过什么了吗?

提前感谢,

托马斯

PS:一件事可能是一个问题可能是mappedBy = "main"不引用实际id列,但我不能改变它为mappedBy = "id"

如果您想在MainEntity和SubEntity之间共享主键,请使用PrimaryKeyJoinColumnMapsId注释。

通过使用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参考文档:

PrimaryKeyJoinColumn
MapsId

有三个选项可以避免n +1的问题:

 Lot size
 subselect
 Make a LEFT JOIN in the query

FAQ1这里FAQ2

相关内容

最新更新