2013-05-19 42 views
3

我使用hibernate的spring-data。我有一個雙向映射如下:JPA 2.0 /休眠 - 爲什麼冬眠問題刪除前選擇計數(*)查詢

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=? 

任何想法爲什麼休眠發出2選擇查詢?沒有選擇的情況下發出刪除查詢是不可能的?

由於

+1

我認爲這個鏈接回答你的問題:http://stackoverflow.com/a/13240979/2387977 – Dherik

回答

1

JPA僅公開關於EntityManager一個remove(…)方法,該方法將被刪除的實體。因此,對於您使用id調用delete(…),我們首先檢查具有該id的實體是否確實存在(第一個查詢)。然後我們實現對象(第二個查詢),最終將其交給EntityManager.remove(…)(查詢3和4)。

其實exists(…)檢查是多餘的,因爲我們可以在第二步中簡單檢查null。我已經創建並修復了DATAJPA-363,這樣您就可以在將來看到更少的查詢。

+0

非常感謝您的響應和修復... – brnzn

+0

一個非常好的理由繞過JPA完全和本機(我往往會越來越多地做這件事) – xtian