0

當我試圖訪問分離實體的惰性@ManyToOne引用的ID時,我正面臨着LazyInitializationException。我不想完全獲取參考,但只需要ID(它應該存在於原始對象中以便以延遲/延遲的方式獲取參考)。LazyInitializationException對@ManyToOne引用的getId()引用

EntityA ea = dao.find(1) // find is @Transactional, but transaction is closed after method exits 
ea.getLazyReference().getId() // here is get exception. lazyReference is a ManyToOne relation and so the foreight key is stored in EntityA side. 

套用,我怎麼能不實際獲取整個LazyReference訪問LazyReference的ID(實際上在最初的選擇存在EntityA)?

+0

的[只是不使用連接在獲得ID列的值可能的複製hibernate對象一對多關係](http://stackoverflow.com/questions/32220951/just-getting-id-column-value-not-using-join-in-hibernate-object-one-to-many-rela) –

+0

感謝您的建議。順便說一句,你提到的問題可能無法清楚地回答任何有我自己的問題的人(雖然我的回答)。答案與LazyInitializationException沒有任何關係,所以當搜索這樣的問題時,人們很難找到它。請在這裏再次回答(@Access),提出另一個問題。 – Mohsen

+0

不客氣。完成後,請參閱下面的答案。 –

回答

3

當使用字段訪問,Hibernate的治療getId()方法相同,任何其他方法,即調用它觸發代理初始化,從而導致LazyInitializationException如果在分離調用實例。

要只能使用id屬性的屬性訪問(同時保持所有其他屬性字段訪問),指定AccessType.PROPERTY的ID字段:

@Entity 
public class A { 
    @Id 
    @Access(AccessType.PROPERTY) 
    private int id; 

    public int getId() { 
    return id; 
    } 

    public void setId(int id) { 
    this.id = id; 
    } 
} 
1

這應該是可能的。我只能得到@ManyToOne LAZY實體的ID。

但是,因爲我已經在實體的getters上設置了註釋,而不是直接在實例變量上設置結果爲空值。

我相信你在實例變量上使用註釋。您可以嘗試getter註釋並查看是否可以幫助您。

+0

是的,我實際上把註釋放在字段而不是getters上。我會嘗試與獲得者並且告訴結果。這是Hibernate的一個bug嗎? – Mohsen

+0

我不認爲這是一個錯誤。我記得閱讀解釋這種行爲的鏈接。我會盡快發佈鏈接。 –

+0

@MadhusudanaReddySunnapu我只是檢查你的建議,它是正確的 - 如果我們在getter上使用註釋,沒有任何'LazyInitializationException'。我不記得在哪種情況下,但有時候,我們的團隊在使用getters註解方法獲取標識符時有這樣的例外情況。 –

0

你會得到一個LazyInitializationException異常,因爲Hibernate會使用代理對象包裝持久對象。代理爲一個懶惰對象的任何獲得者生成一個異常,即使當LazyReference已經擁有id時也是如此。

要獲得id沒有LazyInitializationException你可以使用this method(您可以參閱鏈接其他有趣的utilite方法)

@SuppressWarnings("unchecked") 
public static <T> T getPid(Persistent<?> persistent) { 
    if (persistent == null) { 
     return null; 
    } 

    if (!(persistent instanceof HibernateProxy) || Hibernate.isInitialized(persistent)) { 
     return (T) persistent.getPid(); 
    } 

    LazyInitializer initializer = ((HibernateProxy) persistent).getHibernateLazyInitializer(); 
    return (T) initializer.getIdentifier(); 
} 

Persistent是所有persistents的基類。爲了您的LazyReference你可以重寫這樣的代碼

@SuppressWarnings("unchecked") 
public static Long getId(LazyReference persistent) { 
    if (persistent == null) { 
     return null; 
    } 

    if (!(persistent instanceof HibernateProxy) || Hibernate.isInitialized(persistent)) { 
     return persistent.getId(); 
    } 

    LazyInitializer initializer = 
     ((HibernateProxy) persistent).getHibernateLazyInitializer(); 
    return initializer.getIdentifier(); 
} 
相關問題