[英]JPA entity manager createQuery from entity, different package but same name
[英]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.