使用JPA将哈希存储为字节数组

时间:2010-09-29 12:42:47

标签: database hibernate jpa hash blob

我的User实体类包含密码哈希字段,这是一个具有固定长度的字节数组(32,因为它是SHA-256哈希)。

@Entity
public class User {
    @Column(nullable=false)
    private byte[] passwordHash;
    ...
}

正如你所看到的,我没有用任何特殊的东西注释它,只是一个NOT NULL。

这有效,但会有效吗?我的架构是由Hibernate生成的,但我不确切知道它生成了什么(我目前正在使用内存中的HSQL数据库)。

我很担心,因为它不知道它是一个固定长度的数组(length注释的Column字段仅适用于字符串),它会将此哈希存储在BLOB字段,它作为指针添加到记录中(如果我正确理解数据库是如何工作的)。

这是真的,我怎么能改变这个?我应该只使用base64或hex将哈希值编码为字符串,接受它的性能/正确性影响吗?

4 个答案:

答案 0 :(得分:5)

  

我很担心,因为它不知道它是一个固定长度的数组(Column注释的长度字段仅适用于字符串),(...)

如果指定列长度,Hibernate将使用此信息来确定要生成的SQL列类型(TINYBLOBBLOBMEDIUMBLOBLONGBLOB)。

  

我需要的是BINARY(32)

你试过这个吗?

@Column(columnDefinition="BINARY(32) NOT NULL")
private byte[] passwordHash;

答案 1 :(得分:1)

tinyblob是一个很好的玩笑(mysql types reference),但我的所有应用程序都适用于Strings。 如果您真的关心毫秒,请在分析器中尝试两个版本并查看最佳效果。我首选的分析器是netbeans中包含的分析器。

答案 2 :(得分:0)

据我所知,SHA-256哈希始终只是可打印字符(如果不是,则将其编码为base64),因此解决方案是您可以将其存储为字符串,然后使用length字段Column注释。

然后你有了固定的长度,毫无疑问的表现。

答案 3 :(得分:0)

它可能效率不高,但我建议您使用String作为存储类型,并根据需要使用getter和setter方法进行转换。这允许不同数据库之间的JPA最大可移植性。

我使用与日期/时间类似的技术,通过存储表示UTC时代以来的时间的长片,这样可以避免时区问题(时区信息在所有数据库的数据库日期都不可移植)。