首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Hibernate正在两次选择相同的列。为什么和目的是什么?

Hibernate正在两次选择相同的列。为什么和目的是什么?
EN

Stack Overflow用户
提问于 2022-02-21 02:42:13
回答 2查看 744关注 0票数 1

在下面的Hibernate生成的查询中,student_idcollege_id_fk字段被选中了两次,为什么是这样,目的是什么?这能修好吗。

代码语言:javascript
代码运行次数:0
运行
复制
2022-02-21 07:12:33.213 TRACE 19824 --- [           main] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([student_1_12_0_] : [INTEGER]) - [6]
Hibernate: 
    select
        students0_.college_id_fk as college_3_12_0_,
        students0_.student_id as student_1_12_0_,
        students0_.student_id as student_1_12_1_,
        students0_.college_id_fk as college_3_12_1_,
        students0_.student_name as student_2_12_1_ 
    from
        student students0_ 
    where
        students0_.college_id_fk=?
2022-02-21 07:12:33.214 TRACE 19824 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [INTEGER] - [1]

呼叫代码如下-

代码语言:javascript
代码运行次数:0
运行
复制
  collegeRepo.findAll().forEach( c -> System.err.println("college wit students: " + c.getStudents() ) );

以上是spring数据jpa提供的方法,因此它具有从spring数据jpa实现的功能。

我也经历过类似的问题,这表明实体可能有一些错误,比如映射错误或@Id使用错误。所以,我把我的实体关系贴在这里。

实体关系是-学生属于一所大学,一所大学可以有多个学生。学生

这些实体如下。

(小编辑1-遵循肯的建议,我已经评论了College.students实体的急切加载,但“选择两次”问题仍然存在。)编辑1的结尾)

代码语言:javascript
代码运行次数:0
运行
复制
@Entity
public class College {

    @Id
    @GeneratedValue
    private int collegeId;

    private String collegeName;

    @OneToMany(targetEntity = Student.class, mappedBy = "college") //, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    //as you can see students is loaded eagerly.
    private List<Student> students;

代码语言:javascript
代码运行次数:0
运行
复制
@Entity
public class Student {

    @Id
    @GeneratedValue
    private int studentId;

    private String studentName;

    @ManyToOne
    @JoinColumn(name = "collegeId_fk")
    private College college;

我在搜索引擎上搜索"Hibernate两次选择同一列“。但是没有什么有用的结果。因此,SOF是理解或解决此问题的唯一方法。

应@tgdavies的请求: spring启动版本为2.6.1,hibernate-core版本为5.6.1

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-22 08:40:19

版本6.0之前的Hibernate依赖于为每一列使用而生成的别名。因此,如果您有多个关联,甚至只是一个与许多关联相反的关联,您将看到重复的列选择,因为在6.0之前的Hibernate基于别名获取值。Hibernate 6.0切换到基于位置的抓取和反重复选择为同一列.

票数 2
EN

Stack Overflow用户

发布于 2022-02-21 04:01:00

您提到的select SQL是由大学学生的急切加载触发的。我简要地跟踪了源代码,并将其归结为OneToManyPersister,以便在这里生成select子句。我不知道为什么作者会生成select子句,其中包含一些重复的列,而且我认为除非您使用自己修补的hibernate版本,否则您无法改变这种行为。

如果你真的不希望这种情况发生,我的建议是不要对这所大学的学生使用急切的抓取。毕竟,这是个坏主意,因为急切的抓取会带来N+1查询问题。如果你有100所大学,这样的SQL会重复100次来加载这100所大学的学生。

为了避免N+1查询问题和SQL中的重复列,您可以编写一个JPQL查询,以便将该学院与其学生一起获取连接:

代码语言:javascript
代码运行次数:0
运行
复制
@Query("select distinct c from College c left join fetch c.students")
List<College> findAllCollegeWithStudents();

或者,如果您愿意的话,可以使用@EntityGraph声明性地执行此操作:

代码语言:javascript
代码运行次数:0
运行
复制
@EntityGraph(value = "students")
List<College> findAll(); 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71200665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档