在 SQL Server 2012 数据库中,我有一个包含 varbinary(128) 列的表,该表存储由证书 (AppCert) 支持的密钥 (Secret_Key) 和使用主键的 SHA2_512 哈希的身份验证器加密的数据:
CREATE TABLE [Lookup].[SecretStuff] (
[Id] tinyint NOT NULL,
[Secret] varbinary(128) NOT NULL
CONSTRAINT [PK_Lookup-SecretStuff_Id] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [UN_Lookup-SecretStuff_Secret] UNIQUE NONCLUSTERED ([Secret])
);
OPEN SYMMETRIC KEY [Secret_Key] DECRYPTION BY CERTIFICATE [AppCert];
INSERT INTO [Lookup].[SecretStuff] ([Id], [Secret]) VALUES (1, ENCRYPTBYKEY(KEY_GUID('Secret_Key'), CONVERT(nvarchar(512), 'I have a secret'), 1, HASHBYTES('SHA2_512', CONVERT(varbinary(128), CONVERT(tinyint, 1)))));
CLOSE SYMMETRIC KEY [Secret_Key];
OPEN SYMMETRIC KEY [Secret_Key] DECRYPTION BY CERTIFICATE [AppCert];
SELECT [Id], CONVERT(nvarchar, DECRYPTBYKEY([Secret], 1, HASHBYTES('SHA2_512', CONVERT(varbinary, [Id])))) AS [Secret] FROM [Lookup].[SecretStuff];
CLOSE SYMMETRIC KEY [Secret_Key];
这一切都很好。现在,我有一个使用 JPA/Hibernate 的 Spring Boot 应用程序,该应用程序已连接并经过测试/验证以与该数据库一起使用。SecretStuff 类:
@Entity
@Table(name="SecretStuff", schema="Lookup")
public class SecretStuff {
@Id
@Column(name = "Id",
nullable = false)
private Integer id;
@Column(name = "Secret",
nullable = false,
unique = true)
@Size(min = 1, max = 255)
@ColumnTransformer(
read = "CONVERT(nvarchar(89), DECRYPTBYKEY([Secret], 1,
HASHBYTES('SHA2_512', CONVERT(varbinary(128), [Id]))))")
private String secret;
// getters/setter omitted
}
当我测试 SecretStuff 类时,我看到以下 Hibernate 生成的 SQL:
select
secretstuf0_.Id as Id1_7_0_,
CONVERT(nvarchar(89), DECRYPTBYKEY(secretstuf0_.[Secret],
1,
HASHBYTES('SHA2_512',
CONVERT(varbinary(128),
secretstuf0_.[Id])))) as Secret2_7_0_
from
Lookup.SecretStuff secretstuf0_
where
secretstuf0_.Id=?
执行并返回 Id = 1 Secret = NULL 的 1 行的完全合理的查询,因为在执行查询之前未打开 SYMMETRIC KEY。
我的问题: 如何在查询之前在同一事务中执行 OPEN SYMMETRIC KEY... 命令,在查询之后在同一事务中执行 CLOSE SYMMETRIC KEY... 命令?
我在服务类方法中使用了 Hibernate.initialize 来延迟获取事务中的多对多关系。我会在这里使用类似的方法吗?如何?
我在输入这个问题时看到了这篇文章,但它已经有几年历史了,并且使用了 NativeQuery 的 EntityManager 方法。有没有更新的方法来使用 JPA/Hibernate 来管理这个?