2010-08-05 157 views
12

我有一個用戶實體類,我試圖做密碼散列。我認爲最簡單的方法是創建一個用@Transient註釋的密碼字段和一個在用@PrePersist和@PreUpdate註解的方法持久保存對象之前設置的哈希密碼字段。在@PreUpdate方法被調用之前JPA @Transient字段被清除

所以我有這樣的事情:

@Transient 
private String password; 

private String hashedPassword; 

@PrePersist 
@PreUpdate 
private void hashPassword() { 
    if(password != null) { 
     hashedPassword = PasswordHasher.hashPassword(password); 
    } 
} 

這工作完全正常當實體繼續存在。密碼字段仍然在調用hashPassword時設置,並計算並存儲hashedPassword的值。

但是,對於更新也是如此 - 即使在合併實體之前設置了密碼的新值,在調用hashPassword時該字段爲null。爲什麼是這樣?難道瞬態場的值不應該一直存在,直到實體持續存在?

(我使用的EclipseLink 2.0.0順便說一句,如果這有什麼差別)

+3

可能的重複:http://stackoverflow.com/questions/2581665/jpa-transient-information-lost-on-create – 2010-08-05 01:40:27

+0

是的,這是完全相同的行爲(請參閱** 3.2.4.1合併分離的實體狀態* *規範的合併語義)。 – 2010-08-05 07:21:16

回答

5

我通過更新 UND 插入設置爲false,在 「瞬時」 字段,所以你的情況,這將是解決了這個需要一個表@column(這有點醜),但它永遠不會被填充(這對我來說很重要,因爲安全原因)。

我對Hibernate 4.3.4.Final進行了測試,它爲我工作。該字段值可用於我的EntityLister @PrePersist和@PreUpdate方法,但未存儲在數據庫中。

希望能幫助任何有類似問題的人。

3

如上答覆中提到,這是在規範的設計。 EclipseLink包含一個不屬於JPA規範的事件(postMerge),應該在循環的正確位置爲您調用。在EclipseLink 2.1中,可以使用常規@EventListeners註釋來註冊描述符事件適配器類,在2.1之前,您甚至需要添加甚至使用EclipseLink本機API。

@Column(name = "password", insertable = false, updatable = false) 
private String password; 

因此:

@EntityListeners({ 
    a.b.MyEventListener.class, 
}) 

package a.b; 

import org.eclipse.persistence.descriptors.DescriptorEvent; 
import org.eclipse.persistence.descriptors.DescriptorEventAdapter; 

public class MyEventListener extends DescriptorEventAdapter { 

    public void postMerge(DescriptorEvent event) { 
     //event.getSession(); 
     //event.getObject(); 
     //event.getOriginalObject(); 
    } 
} 
+0

由於某種原因,如果我這樣做了postMere方法,但我的PrePersist和PreUpdate方法被忽略。任何想法? – javydreamercsw 2017-05-15 15:41:48