Hibernate N+1 关于 OneToOne 关系的问题

saa*_*une 4 hibernate jpa spring-data-jpa

我在 ORM 的 Spring Boot 应用程序中将 spring-data-jpa 与 hibernate 结合使用。我在生成 N+1 查询时遇到 OneToOne 关系问题,但我不需要获取 oneToOne 对象。

我的 OneToOne 关系是 EAGERLY fetched,我尝试使用惰性和 fetch 模式来 JOIN,但仍然无法让它只生成一个查询。

这是实体和查询的代码:

@Entity
@Table(name = "item")
public class Item implements Serializable {

   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
   @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

   @Column(name = "number")
   private String number;

   @Column(name = "date")
   private LocalDate date;

    @OneToOne(mappedBy = "item", fetch = FetchType.EAGER)
    @JsonIgnore
    private Status status;

}

@Entity
@Table(name = "status")
public class Status implements Serializable {

   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
   @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

   @OneToOne(fetch = FetchType.EAGER)
   @JoinColumn(unique = true)
   private Item item;

}
Run Code Online (Sandbox Code Playgroud)

这是存储库中的查询:

@Query(value = "SELECT * FROM ( SELECT  number, MAX(date) AS date FROM item WHERE date < ? GROUP BY number) AS latest_it INNER JOIN item ON item.number = latest_it.number AND item.date = latest_it.date", nativeQuery = true)
List<Item> findLatestByNumberAndDate(LocalDate localDate);
Run Code Online (Sandbox Code Playgroud)

当我运行查询时,我收到查询音:

select status0_.id ... from status status0_ left outer join item item1_ on status0_.item_id=item1_.id left outer join status status2_ on item1_.id=status2_.item_id where status0_.item_id=?
Run Code Online (Sandbox Code Playgroud)

而我期望的是只看到执行的存储库中定义的查询。这个问题对性能来说是一个真正的痛苦。

你对此有什么提示吗?

谢谢

Ybr*_*bri 5

通过执行本机查询,您不使用 Hibernate Fetch 配置。

您可以执行 JPQL,而不是在状态上使用 JOIN FETCH 来获取查询中的状态并避免额外的查询:

@Query(value = "
    SELECT *, MAX(date)
    FROM Item i
    LEFT JOIN FETCH i.status 
    GROUP BY i.number
    HAVING i.date < ?"
)
List<Item> findLatestByNumberAndDate(LocalDate localDate);
Run Code Online (Sandbox Code Playgroud)

否则,请查看这篇文章,它将向您展示使 OneToOne 懒惰的不同可能性:使 OneToOne 关系变得懒惰