【问题标题】:JPA 2.0 / Hibernate - why hibernate issue select count (*) query before deleteJPA 2.0 / Hibernate - 为什么在删除之前休眠问题选择计数(*)查询
【发布时间】:2013-05-14 09:44:30
【问题描述】:

我正在将 spring-data 与休眠一起使用。我有一个双向映射如下:

public class Student {
   ...
   @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true,    mappedBy="student")
   private List<StudentLog> logs = newArrayList();  
   ...
}

public class StudentLog {
   .....
    @ManyToOne(cascade = CascadeType.REFRESH, optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "STUDENT_ID" , insertable = true, updatable = false, nullable =false)
    private Student student;
   .....
}

当我使用 JpaRepository 删除学生时:repo.delete(s.getId());我可以看到以下查询

Hibernate: select count(*) as col_0_0_ from STUDENTS student0_ where student0_.ID=? and 1=1
Hibernate: select student0_.ID as ID1_2_2_, student0_.FIRST_NAME as FIRST2_2_2_,  educationh1_.STUDENT_ID as STUDENT6_2_4_, educationh1_.ID as ID1_0_4_, educationh1_.ID as  ID1_0_0_, educationh1_.CLASS as CLASS2_0_0_, educationh1_.LEVEL as LEVEL3_0_0_, educationh1_.PREDICTED_END_DATE as PREDICTE4_0_0_, educationh1_.START_DATE as START5_0_0_, educationh1_.STUDENT_ID as STUDENT6_0_0_, educationh1_.TERM as TERM7_0_0_, logs2_.STUDENT_ID as STUDENT3_2_5_, logs2_.ID as ID1_3_5_, logs2_.ID as ID1_3_1_, logs2_.LOG as LOG2_3_1_, logs2_.STUDENT_ID as STUDENT3_3_1_ from STUDENTS student0_ left outer join EDUCATION_HISTORY educationh1_ on student0_.ID=educationh1_.STUDENT_ID left outer join STUDENT_LOG logs2_ on student0_.ID=logs2_.STUDENT_ID where student0_.ID=?
Hibernate: delete from STUDENT_LOG where ID=?
Hibernate: delete from STUDENTS where ID=?

知道为什么 hibernate 会发出 2 个选择查询吗?没有选择就不能只发出删除查询吗?

谢谢

【问题讨论】:

标签: hibernate jpa spring-data jpa-2.0 bidirectional


【解决方案1】:

JPA 仅在 EntityManager 上公开了一个 remove(…) 方法,该方法需要删除实体。因此,对于您使用 id 调用 delete(…) 时,我们首先检查具有 id 的实体是否真的存在(第一次查询)。然后我们具体化对象(第二个查询),最终将其交给EntityManager.remove(…)(查询 3 和 4)。

实际上exists(…) 检查是多余的,因为我们可以在第二步中简单地检查null。我已经创建并修复了DATAJPA-363,这样您以后应该会少看到一个查询。

【讨论】:

  • 完全绕过 JPA 并采用原生方式的一个很好的理由(我倾向于越来越频繁地这样做)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-02
  • 1970-01-01
  • 2011-02-16
  • 2011-07-20
相关资源
最近更新 更多