我有一个User Entity类,我正在尝试进行密码散列。我认为最简单的方法是创建一个用@Transient注释的密码字段和一个哈希密码字段,该密码字段是在使用@PrePersist和@PreUpdate注释的方法持久化对象之前设置的。
所以我有这样的事情:
@Transient
private String password;
private String hashedPassword;
@PrePersist
@PreUpdate
private void hashPassword() {
if(password != null) {
hashedPassword = PasswordHasher.hashPassword(password);
}
}
当实体被持久化时,这非常适用。密码字段仍然由调用hashPassword的时间设置,并且计算并存储hashedPassword的值。
但是,对于更新也是如此 - 即使在合并实体之前设置了密码的新值,该字段在调用hashPassword时也为空。为什么是这样?至少在实体持续存在之前,瞬态字段的值是否应该保持不变?
(我正在使用EclipseLink 2.0.0 btw,如果它有任何区别的话)
答案 0 :(得分:5)
我通过在“transient”字段上将可更新和可插入设置为false来解决此问题,因此在您的情况下,这将是:
@Column(name = "password", insertable = false, updatable = false)
private String password;
因此需要一个表@column(这有点难看)但它永远不会被填充(出于安全考虑,这在我的情况下很重要)。
我测试了Hibernate 4.3.4.Final,它对我有用。字段值可用于我的EntityLister @PrePersist和@PreUpdate方法,但未存储在数据库中。
希望能帮助任何有类似问题的人。
答案 1 :(得分:3)
如上面的答案所述,这是在规范中设计的。 EclipseLink包含一个事件(postMerge),它不属于JPA规范,应该在循环中的正确点为您调用。在EclipseLink 2.1中可以使用常规@EventListeners注释来注册Descriptor Event Adapter类,在2.1之前,您需要使用EclipseLink本机API添加它。
@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();
}
}