繁体   English   中英

Oracle中CHAR主键列上的休眠和填充

[英]Hibernate and padding on CHAR primary key column in Oracle

我在Oracle中使用带有char(6)列的Hibernate时遇到了一些麻烦。 这是表的结构:

CREATE TABLE ACCEPTANCE
(
   USER_ID char(6) PRIMARY KEY NOT NULL,
   ACCEPT_DATE date
);

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

select * from acceptance where user_id = "abc"

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

em.find(Acceptance.class, "abc");

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

em.find(Acceptance.class, "abc   ");

我正在处理的模块从用户系统的其他部分取消用户ID。 是否有更好的方法让Hibernate工作,而不是在将代码用于将用户ID调整到一定长度之后再将其提供给Hibernate? (如果长度发生变化,可能会出现维护问题)

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

但是,严重的是,由于您的user_id在您的实体中被映射为String,因此Hibernate的Oracle方言将其转换为varchar 由于Hibernate为其所有查询使用预处理语句,因此该语义会延续(与SQuirreL不同,其中值被指定为文字,因此以不同方式进行转换)。

基于Oracle 类型转换规则,然后将列值提升为varchar2并进行比较; 因此你没有记录。

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

为什么你的模块从系统的其他部分获得未填充的值?

根据我的理解,如果系统的其他部分不改变PK,他们应该从数据库中读取6个字符,并在整个过程中传递6个字符 - 这没关系。 唯一的例外是生成PK时,在这种情况下可能需要填充。

您可以避免这个问题(通过每次必要时修剪或填充值),但它不能解决您的PK未得到一致处理的问题。 要提前解决问题,您必须更进一步

  • 总是从模块的其他部分接收6个字符
  • 使用varchar2正确处理动态大小

如果你不能提前解决问题,那么你确实需要

  • 必要时在周围添加修剪/填充
  • 如果有的话,在DAO中添加修剪/填充
  • 如果有效,请在用户类型中添加修剪/填充(来自N. Hughes的建议)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM