有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在没有N+1查询的情况下选择@OneToOne实体(批处理)?

想象一下下面的场景。。。我们有两个不同的实体,通过@OneToOne注释连接-

@javax.persistence.Entity
@Table(name = "spawner")
@Access(value = AccessType.FIELD)
public class Spawner extends HibernateComponent {

    @OneToOne
    @JoinColumn(name = "location_id", referencedColumnName = "identity_id")
    @Fetch(FetchMode.JOIN)
    public Location location;

    public Spawner() { }
@Entity
@Table(name = "location")
@Access(AccessType.FIELD)
public class Location extends HibernateComponent {

    @ManyToOne
    @JoinColumn(name = "chunk_id", referencedColumnName = "identity_id", updatable = false)
    @Fetch(FetchMode.JOIN)
    public Chunk chunk;

    public Location() {}
}

当我们用下面的语句选择Spawnersession.createQuery("select s from Spawner s where s in (...)");hibernate生成如下所示的输出

Hibernate: select identity0_.id as id1_2_0_, location1_.identity_id as identity1_6_1_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_, location1_.chunk_id as chunk_id4_6_1_, location1_.x as x2_6_1_, location1_.y as y3_6_1_ from identity identity0_ inner join location location1_ on (location1_.identity_id=identity0_.id and (identity0_.id in (8326589099709645653 , 6287325594386187920 , 5407611297503526929 , 8523982519594665733 , 4028725686660451036 , 4729790674605130415 , 6901230747306707572 , 89683718271946391 , 663547951024983400 , 487871300966958647 , 2986281183600263327 , 7129934223659254130 , 7423461182852450838 , 6258927419235452915 , 4756503673250530721 , 7989242675644875262 , 7502164321920434546 , 9125201177335319448 , 5276750027792075277 , 2958385004616501743 , 8131213851438696494 , 5378786184839581257 , 4800722432645154706)))
Hibernate: select chunk0_.identity_id as identity1_0_0_, chunk0_.createdOn as createdo2_0_0_, chunk0_.x as x3_0_0_, chunk0_.y as y4_0_0_, inchunk1_.Chunk_identity_id as chunk_id1_1_1_, identity2_.id as inchunk_2_1_1_, identity2_.id as id1_2_2_, identity2_.tag as tag2_2_2_, identity2_.typeID as typeid3_2_2_ from chunk chunk0_ left outer join chunk_identity inchunk1_ on chunk0_.identity_id=inchunk1_.Chunk_identity_id left outer join identity identity2_ on inchunk1_.inChunk_id=identity2_.id where chunk0_.identity_id=?
Hibernate: select identity0_.id as id1_2_0_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_ from identity identity0_ where identity0_.id=?
Hibernate: select chunk0_.identity_id as identity1_0_0_, chunk0_.createdOn as createdo2_0_0_, chunk0_.x as x3_0_0_, chunk0_.y as y4_0_0_, inchunk1_.Chunk_identity_id as chunk_id1_1_1_, identity2_.id as inchunk_2_1_1_, identity2_.id as id1_2_2_, identity2_.tag as tag2_2_2_, identity2_.typeID as typeid3_2_2_ from chunk chunk0_ left outer join chunk_identity inchunk1_ on chunk0_.identity_id=inchunk1_.Chunk_identity_id left outer join identity identity2_ on inchunk1_.inChunk_id=identity2_.id where chunk0_.identity_id=?
Hibernate: select identity0_.id as id1_2_0_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_ from identity identity0_ where identity0_.id=?
Hibernate: select chunk0_.identity_id as identity1_0_0_, chunk0_.createdOn as createdo2_0_0_, chunk0_.x as x3_0_0_, chunk0_.y as y4_0_0_, inchunk1_.Chunk_identity_id as chunk_id1_1_1_, identity2_.id as inchunk_2_1_1_, identity2_.id as id1_2_2_, identity2_.tag as tag2_2_2_, identity2_.typeID as typeid3_2_2_ from chunk chunk0_ left outer join chunk_identity inchunk1_ on chunk0_.identity_id=inchunk1_.Chunk_identity_id left outer join identity identity2_ on inchunk1_.inChunk_id=identity2_.id where chunk0_.identity_id=?
Hibernate: select identity0_.id as id1_2_0_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_ from identity identity0_ where identity0_.id=?
Hibernate: select chunk0_.identity_id as identity1_0_0_, chunk0_.createdOn as createdo2_0_0_, chunk0_.x as x3_0_0_, chunk0_.y as y4_0_0_, inchunk1_.Chunk_identity_id as chunk_id1_1_1_, identity2_.id as inchunk_2_1_1_, identity2_.id as id1_2_2_, identity2_.tag as tag2_2_2_, identity2_.typeID as typeid3_2_2_ from chunk chunk0_ left outer join chunk_identity inchunk1_ on chunk0_.identity_id=inchunk1_.Chunk_identity_id left outer join identity identity2_ on inchunk1_.inChunk_id=identity2_.id where chunk0_.identity_id=?
Hibernate: select identity0_.id as id1_2_0_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_ from identity identity0_ where identity0_.id=?
Hibernate: select chunk0_.identity_id as identity1_0_0_, chunk0_.createdOn as createdo2_0_0_, chunk0_.x as x3_0_0_, chunk0_.y as y4_0_0_, inchunk1_.Chunk_identity_id as chunk_id1_1_1_, identity2_.id as inchunk_2_1_1_, identity2_.id as id1_2_2_, identity2_.tag as tag2_2_2_, identity2_.typeID as typeid3_2_2_ from chunk chunk0_ left outer join chunk_identity inchunk1_ on chunk0_.identity_id=inchunk1_.Chunk_identity_id left outer join identity identity2_ on inchunk1_.inChunk_id=identity2_.id where chunk0_.identity_id=?
Hibernate: select identity0_.id as id1_2_0_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_ from identity identity0_ where identity0_.id=?
Hibernate: select chunk0_.identity_id as identity1_0_0_, chunk0_.createdOn as createdo2_0_0_, chunk0_.x as x3_0_0_, chunk0_.y as y4_0_0_, inchunk1_.Chunk_identity_id as chunk_id1_1_1_, identity2_.id as inchunk_2_1_1_, identity2_.id as id1_2_2_, identity2_.tag as tag2_2_2_, identity2_.typeID as typeid3_2_2_ from chunk chunk0_ left outer join chunk_identity inchunk1_ on chunk0_.identity_id=inchunk1_.Chunk_identity_id left outer join identity identity2_ on inchunk1_.inChunk_id=identity2_.id where chunk0_.identity_id=?
Hibernate: select identity0_.id as id1_2_0_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_ from identity identity0_ where identity0_.id=?
Hibernate: select chunk0_.identity_id as identity1_0_0_, chunk0_.createdOn as createdo2_0_0_, chunk0_.x as x3_0_0_, chunk0_.y as y4_0_0_, inchunk1_.Chunk_identity_id as chunk_id1_1_1_, identity2_.id as inchunk_2_1_1_, identity2_.id as id1_2_2_, identity2_.tag as tag2_2_2_, identity2_.typeID as typeid3_2_2_ from chunk chunk0_ left outer join chunk_identity inchunk1_ on chunk0_.identity_id=inchunk1_.Chunk_identity_id left outer join identity identity2_ on inchunk1_.inChunk_id=identity2_.id where chunk0_.identity_id=?
Hibernate: select identity0_.id as id1_2_0_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_ from identity identity0_ where identity0_.id=?
Hibernate: select chunk0_.identity_id as identity1_0_0_, chunk0_.createdOn as createdo2_0_0_, chunk0_.x as x3_0_0_, chunk0_.y as y4_0_0_, inchunk1_.Chunk_identity_id as chunk_id1_1_1_, identity2_.id as inchunk_2_1_1_, identity2_.id as id1_2_2_, identity2_.tag as tag2_2_2_, identity2_.typeID as typeid3_2_2_ from chunk chunk0_ left outer join chunk_identity inchunk1_ on chunk0_.identity_id=inchunk1_.Chunk_identity_id left outer join identity identity2_ on inchunk1_.inChunk_id=identity2_.id where chunk0_.identity_id=?
Hibernate: select identity0_.id as id1_2_0_, identity0_.tag as tag2_2_0_, identity0_.typeID as typeid3_2_0_ from identity identity0_ where identity0_.id=?

正如您所见,hibernate遇到了n+1问题,并对每个加载的位置执行一个“选择块查询”

我们如何防止这种情况,并强制他们批处理/加入到执行的查询中?我们仍然希望加载“位置”引用和“块”引用。。。因此,我们不想在加载“生成程序”时忽略它们,相反,我们的目标是批量执行查询,以选择位置中的“位置”和“块”

有什么想法吗?我们如何在hibernate中实现这一点


共 (0) 个答案