java - Hibernate 左连接获取许多返回的口是心非

标签 java sql spring hibernate spring-data

我有一个问题,我通过 Spring 数据使用 Hibernate,并且我有这个数据模型(模型要大得多,但这是导致问题的部分)。

假设我们有实体 A实体 B。 两个实体之间的关系是多对多

我正在尝试使用已获取记录B来获取A记录(以防止延迟加载)。

模型是这样连接的

在实体 A 上:

@ManyToMany(mappedBy = "items")
private List<BEntity> bs = new ArrayList<>();

在实体 B 上

@ManyToMany
@JoinTable(
        name = "a_b",
        joinColumns = { @JoinColumn(name = "b_id", referencedColumnName = "id") },
        inverseJoinColumns = { @JoinColumn(name = "a_id", referencedColumnName = "id") }
)
private Collection<AEntity> as = new ArrayList<>();

这是典型的 M:N 关系。我正在尝试检索如下所示的 A 数据

@Query("SELECT a FROM AEntity a " +
        "   LEFT JOIN FETCH a.bs" +
        "WHERE a.id IN (:aIds)")
List<AEntity> findX(@NonNull @Param("aIds") Collection<Long> aIds);

生成的 SQL 类似于

select X -- select fields omitted for simplicity
from item itembo0_
         left outer join a_b ab on a.id = ab.a_id
         left outer join b b on ab.b_id = b.id
where a.id in (...)

这是我所期望的。 SQL 会导致重复(我也预料到这一点,因为可能有许多 B 记录,每个记录都有一个结果行)。但最后,hibernate 不会将所有这些行合并到具有获取的 B 字段的 A 实体

例如,当我将 5 个 IDS 传递到“in”状态时,我会得到 10 个 A 记录。 每条都有2条B记录链接!这就是奇怪的部分

有谁能告诉我为什么hibernate不通过A.id标识符合并这些SQL结果并产生重复吗?是因为我要求的是 List 而不是 Set 吗?

最佳答案

在查询中使用“DISTINCT”关键字应该足以避免重复:

@Query("SELECT DISTINCT a FROM AEntity a " +
        "   LEFT JOIN FETCH a.bs" +
        "WHERE a.id IN (:aIds)")
List<AEntity> findX(@NonNull @Param("aIds") Collection<Long> aIds);

我不知道你存储什么类型的数据,但正如你提到的,也许更好的解决方案是使用 Set 而不是 List。

关于java - Hibernate 左连接获取许多返回的口是心非,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68818755/

相关文章:

java - Android:自定义Listview项目 - 强制在一行

java - Android 应用程序已停止并出现 NoClassDefFoundError

java - ModelAndView中重新发送请求参数

java - 如何在 Spring Boot @Async 中使用 ForkJoinPool?

java - jdbctemplate 和乐观锁

java - 是否有一种 Java 数据结构可以返回对象集合中的一组特定属性?

sql - oracle时间戳到postgres时间戳的转换?

sql - 如何展平 PostgreSQL 结果

php - 按字母和数字排序 MySQL 结果(A1、B2、B3、C2)

java - 带有泛型的自动增长列表