簡體   English   中英

使用來自Hibernate實體管理器的find和createQuery的不同SQL

[英]Different SQL using find and createQuery from Hibernate entity manager

我正在使用Hibernate 3.3.0.GA,我注意到一些奇怪的行為,沒有記錄(我認為)。

我注意到, entityManager.createQuery無法解析我的實體的EAGER關系,而entityManager.find無法解決。

例如,如果我有一個實體:

@Entity
public class Person {

     @Id
     private int id;

     private String name;

     @ManyToOne //EAGER by default in JPA
     private Address address;

}

使用entityManager.find(Person.class, 1L)生成的SQL:

select
    person0_.id as id1_1_,
    person0_.address_id as address3_1_1_,
    person0_.name as name1_1_,
    address1_.id as id2_0_ 
from
    Person person0_ 
left outer join
    Address address1_ 
        on person0_.address_id=address1_.id 
where
    person0_.id=?

以及使用entityManager.createQuery("SELECT p FROM Person where id = 1")生成的SQL:

select
    person0_.id as id1_,
    person0_.address_id as address3_1_,
    person0_.name as name1_ 
from
    Person person0_ 
where
    person0_.id=?

那么,有沒有關於為什么發生這種情況的解釋? 對我來說,兩者都必須具有相同的行為。

工作實例

我使用Hibernate 4.1.6.Final在我的存儲庫中創建了一個顯示該問題的示例: https : //github.com/dherik/hibernate-find-em-so-question 只需使用mvn clean install ,控制台將打印查詢。

更新

@KlausGroenbaek表示EclipseLink 2.5.2在這兩種方法中具有相同的行為。 他也做了一個Hibernate示例,並且在兩種方法中都獲得了相似的結果( find它執行createQuery提取,而createQuery則進行多次選擇,從定義createQuery都是EAGER )。

我查看了您的示例,並對其進行了修復,其工作原理與HiberNate 5.2.5 find()使用createQuery並且createQuery使用多個選擇一樣。

在您的示例中看不到該信息的原因是因為您的數據庫中沒有DATA ,find仍然進行聯接,但是由於DB中沒有Person,因此不需要查找任何Address,因此第二選擇丟失。

但是,您會注意到,即使將數據添加到示例中,從地址選擇也不會顯示。 這是因為從使用find()以來,該地址已經在Persistence Context中,因此無需再次加載它-實際上,如果JPA 必須已經在Persistence中加載了該地址,則JPA 必須返回該地址的完全相同的Java實例。語境。 如果插入em.clear()或使用其他持久性上下文(EntityManager),則會看到選擇內容,因為該地址尚未加載。

您的示例只是一個示例,但是絕對禁止在字段中存儲應用程序管理的EntityManager的方式,當您自己管理自己時,它們應始終是局部變量。 如果使用容器管理的EntityManager(Spring JavaEE),則在使用@PersistenceContext進行注入時,它們可以是字段,但這僅是因為注入的EntityManager是存儲狀態的代理,它是ThreadLocal。

自2009年以來,我已經廣泛使用了JPA,一開始我犯了很多錯誤,因為我不完全了解持久性上下文是什么,所以我有重疊的EntityManager,未維護的雙向關系,而且我還沒有完全理解實體狀態,或容器與應用程序托管的EntityManager。 我從中學到了很多困難的方法(對我來說,這是調試和閱讀EclipseLink源代碼)。 回顧過去,我絕對應該買一本書以獲取全局,而不是通過隨機搜索我所遇到的問題來解決問題。 對於沒有讀過JPA文檔,一本好書或一篇專業文章的人,請幫自己一個忙,並從我的錯誤中學習。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM