一起使用Hibernate Persistence和Validation的正确方法

时间:2013-08-14 11:28:35

标签: hibernate java-ee hibernate-validator

我有使用hibernate持久性和hibernate验证的情况,虽然我已经想到了一些hack-ish方法,但我不知道使用hibernate持久性和验证来解决这个问题的最佳方法。

简单地说,我有一个User对象,我想坚持下去。但在我坚持之前,我想验证它。非常标准的东西。

现在,User对象有一个密码,我们有关于有效密码的规则。例如:最少8个字符,包括至少1个数字等...我想验证这些事情。

但是当我坚持下去时,我需要加密/加密/哈希密码。但是在我进行盐析/散列后,显然没有合理的方法对密码进行上述验证。

所以,我认为我可以使用@PrePersist和@PreUpdate注释。我的想法是在User类中我有一个名为onCreate()的方法。我用@PrePersist标记了它,我做了类似的事情(我对onUpdate()有类似的东西):

@PrePersist
protected void onCreate() {
    encryptPassword();
}

我认为当我调用entityManager.persist()时,它首先调用验证,然后调用onCreate()然后继续。因此验证将验证原始的,非盐渍/哈希密码。盐腌/散列会在以后发生。

当我运行测试并进行调试时,我发现在验证运行之前调用标记为@PrePersist的方法意味着我无法再验证我的密码。

如何将密码的salting / hashing正确挂钩到entityManager.persist()生命周期中,以便我可以正确验证并在该salt和hash之后并最终持久化?

感谢。

1 个答案:

答案 0 :(得分:1)

使用两个bean属性,一个用于持久性,另一个用于验证/转换。像这样:

@Entity
@MyCustomConstraint(...)
public class User implements Serializable {

    // place persistence annotations here, for example
    @Lob @Column(...)
    private byte[] hashedPassword;
    // place validation constraints here, for example
    @Size(min = 8, max = 16)
    @Transient
    private String password;

    public byte[] getHashedPassword() {
        return this.hashedPassword;
    }

    protected void setHashedPassword(byte[] hashedPassword) {
        this.hashedPassword = hashedPassword;
    }

    public void setPassword(String password) {
        this.password = password;
        this.setHashedPassword(this.hashAndSaltMyPassword(this.password));
    }

    protected String getPassword() {
        return this.password;
    }

    protected byte[] hashAndSaltMyPassword(String password) {
        ...
    }
}

完成。