Oracle 中 CHAR 主键列的 Hibernate 和填充

jth*_*thg 5 java oracle hibernate jpa

我在 Oracle 中使用 Hibernate 和 char(6) 列时遇到了一些问题。该表的结构如下:

CREATE TABLE ACCEPTANCE
(
   USER_ID char(6) PRIMARY KEY NOT NULL,
   ACCEPT_DATE date
);
Run Code Online (Sandbox Code Playgroud)

对于用户 ID 少于 6 个字符的记录,我可以在使用 SQuirreL 运行查询时选择它们,而无需填充用户 ID。IE 如果存在用户 ID 为“abc”的记录,则以下命令将返回一条记录。

select * from acceptance where user_id = "abc"
Run Code Online (Sandbox Code Playgroud)

不幸的是,当通过 Hibernate (JPA) 进行选择时,以下返回 null:

em.find(Acceptance.class, "abc");
Run Code Online (Sandbox Code Playgroud)

如果我填充该值,它会返回正确的记录:

em.find(Acceptance.class, "abc   ");
Run Code Online (Sandbox Code Playgroud)

我正在开发的模块从系统的其他部分获取未填充的用户 ID。除了在将用户 ID 提供给 Hibernate 之前将其调整为一定长度的代码之外,是否有更好的方法让 Hibernate 工作?(如果长度发生变化,可能会出现维护问题)

Chs*_*y76 3

这是上帝告诉你永远不要使用 CHAR() 作为主键的方式:-)

然而,说真的,由于您user_id在实体中被映射为 String,Hibernate 的 Oracle 方言会将其转换为varchar. 由于 Hibernate 对所有查询都使用准备好的语句,因此该语义会保留下来(与 SQuirreL 不同,SQuirreL 中的值被指定为文字,因此会进行不同的转换)。

然后根据 Oracle类型转换规则将列值提升varchar2并进行比较;因此你拿不回任何记录。

如果您无法更改基础列类型,那么最好的选择可能是使用rtrim()Oracle 方言支持的 HQL 查询和函数。