2015-03-31 19 views
4

我使用JPA 2.1和Hibernate 4.3.7JPA Hibernate延遲多到一個獲取代理

我試圖調節我的應用程序,所以我把懶關係,只獲取什麼,我需要他們

當我重新加載實體時轉爲懶惰時,我遇到了多對一關係的問題即使我獲取實體並且此代理未在視圖部分(JSF)中工作,Hibernate也會用代理替換實體的應用程序。 問題disapear時多到一個是渴望模式,但冬眠執行一個選擇更多每個許多到一個即使我不需要他們

@Entity 
public class Department { 
    @Id 
    private Integer id; 

    //... 
} 

1/

@Entity 
public class Employee { 
    @Id 
    private Integer id; 

    @ManyToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinColumn(name = "id_department", referencedColumnName = "id") 
    private Department department; 

    //... 
} 

的JPQL查詢:

SELECT e FROM Employee e LEFT JOIN FETCH e.department WHERE e.id=:id 

=>一個選擇查詢=>速度快,但部門型機關_ $$ _ jvst3ac_5f的,這確實代理(employee.getDepartment()的getClass()另一方面,getCanonicalName()。)

SELECT e FROM Employee e WHERE e.id=:id 

=> 2個選擇=>慢,但部門加載爲系和一切:在應用程序

2/

@Entity 
public class Employee { 
    @Id 
    private Integer id; 

    @ManyToOne(fetch = FetchType.EAGER, optional = true) 
    @JoinColumn(name = "id_department", referencedColumnName = "id") 
    private Department department; 

    //... 
} 

的JPQL查詢的視圖部分不能正常工作在應用程序的視圖部分中處於良好狀態

該關係是單向的,部門沒有參照僱員

當使用FETCH JOIN時,這可能使部門沒有代理嗎?


後Luiggi的迴應,我將一種高精度的數據獲取與懶惰多到一個+ fetch連接。當我做一個employee.getDepartment()。toString()時我有Department {id = 11,...}但這個部門的類仍然是Department _ $$ _ jvst3ac_5f。原因我不知道,即使數據被提取,JSF/PrimeFaces selectOneMenu組件也不能正常工作HibernateProxy

我嘗試使用Hibernate批註@LazyToOne(LazyToOneOption.FALSE),另外還有@ManyToOne (fetch = FetchType.LAZY),但結果類似於@ManyToOne(fetch = FetchType.EAGER)單獨...

+0

嗨,我知道這是相當一段時間,你有這個問題,但你找到了這個問題的優雅解決方案? – Tarator 2016-08-09 19:58:32

回答

2

問題是,當您使用延遲加載時,您將獲得類的代理已經聲明),並且該代理只有在休眠會話仍然打開的情況下才能從數據庫獲取數據。好像您的會話在將數據返回到視圖時正在關閉,所以當試圖在視圖中使用延遲加載的字段時,您會收到異常。

可能的解決方案:

  • 保留字段提取渴望和付出的開銷對你的實體每個查詢(大概這是不好的,可能會影響性能,但它是一個解決方案)。
  • 在Hibernate會話關閉之前,將您的字段保持爲懶惰並使用正確的get方法,以便代理檢索會話關閉後要使用的相關數據。
+0

是的,保持領域的渴望似乎是不幸的唯一的解決方案,以避免多選擇我添加一個左加入FETCH部門在evry查詢,即使不需要部門(因爲我在我的職位使用get精簡不是一個解決方案) – kwisatz 2015-04-01 09:10:45

+0

@ kwisatz這是一個解決方案,你不能使用這種方法的事實是一個不同的故事。 – 2015-04-01 13:13:39

+0

這不是hibernate中的錯誤嗎?如果我在自己的事務中執行一個查詢,並且它有一些懶惰的字段沒有被初始化,然後在一個新的事務中,我做了一個不同的查詢,在這種情況下,先前懶惰的字段的同一個實體加載現在從數據庫中急切地獲取,不應該那個領域更新與新的熱切取得的實體? – chrismarx 2015-09-03 13:36:20

相關問題