2013-09-26 93 views
3

我有一個類用戶持有認證用戶在我的Web應用程序的電子郵件地址和密碼。該用戶通過JPA/Eclipselink映射到數據庫。JPA:如何排除從數據庫表加載某些領域

我的問題是,我如何防止JPA從數據庫加載密碼字段?因爲我將訪問我的Web應用程序中的用戶對象,所以我將安全性發送到瀏覽器時感到不舒服。

有沒有什麼辦法可以防止在JPA/EclipseLink中加載字段?聲明場瞬態不是一種選擇,因爲當我在用戶對象上調用persist()時,我想將它存儲在數據庫中。

感謝, fredddmadison

+2

使用JPA將它加載到服務器內存中並將其發送到瀏覽器之間存在巨大差異。您應該修正的是您發送給瀏覽器的數據,而不是使用JPA加載的數據。 JPA因此不適合觀看。看看你如何發送數據到瀏覽器。 –

回答

1

JB Nizet有一個正確的觀點。檢索它並在Http響應中序列化是兩個獨立的問題。

我不確定你用什麼來序列化你的數據。如果它是REST API,請考慮Jackson的@JsonIgnore註釋或Eclipselink MOXy的@XmlTransient等效項。如果這使用Java EL(facelets,jsps),則應該只能選擇感興趣的bean屬性。

如果您在檢索過程中確實需要這樣做,請考慮JPQL/Criteria API的構造函數。確保該對象具有接受指定參數的構造函數,並且請記住,如果以此方式檢索,則不會在持久性上下文中進行管理。

SELECT NEW my.package.User(u.id, u.name, u.etc) FROM User u

另外,考慮@PostLoad生命週期回調。

@PostLoad 
private void postLoad() { 
    this.password = null; 
} 

最後,這可能不是這種情況,但我想強化一個概念,即密碼不應該以明文存儲。我提到這一點,因爲返回使用安全算法(bCrypt,多次迭代SHA-512等)的散列醃製密碼並不是什麼大不了的事情(但仍然不理想)。

+0

感謝您的詳細解答。由於我使用了Jackson API,我想我會用@JsonIgnore來嘗試。這似乎很容易排除密碼和其他字段。但是,由於這是通過註釋完成的,因此我無法動態地改變不同用例的行爲。所以postLoad()似乎是一個選擇。 –

0

我有類似的問題。但在我的情況下,我在Entity類中有許多@OneToMany關係,其中一些是EAGER。當我查詢這個實體時,它會加載所有這些實體,但對於Web服務,我只需要其中的一部分。 我試過TupleQuery。但是這不是解決方案,因爲需要OneToMany關係,我必須加入並獲取主查詢的許多重複行。它使得結果更經濟,而不是經濟。