我正在使用Hibernate 4.0.0.Final作为应用程序的JPA持久性提供程序,使用Oracle 11g数据库(使用UTF-8编码创建)和Oracle WebLogic 11g作为应用程序服务器。 persistence.xml
中配置的方言为org.hibernate.dialect.OracleDialect
。
在我的实体中,我正在映射字符串字段,如下所示:
@Column(length=20)
private String description;
我让JPA处理数据库中表的创建。令我惊讶的是,在数据库中,前一个字段的列定义如下所示:
DESCRIPTION VARCHAR2(80 BYTE)
当我在description
字段中插入一个值时(使用SQL控制台而不是应用程序),我最多可以插入80个字符,而不是我预期的20个字符。
这里有什么问题?我想用80字节创建列定义以允许存储UTF-8字符,但它与数据库级别的字段的预期最大长度混淆。理想情况下,我希望该字段看起来像这样:
DESCRIPTION VARCHAR2(20 CHAR)
但我不知道如何配置Hibernate以使用CHAR
而不是BYTE
映射字符串字段。有什么想法吗?
答案 0 :(得分:3)
我用作方言org.hibernate.dialect.OracleDialect
的事实导致了这个问题。我挖掘了源代码,这一行出现在OracleDialect
类:
registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" );
实际上,这是一个众所周知的issue。默认情况下,Oracle为先前的定义生成varchar2($l byte)
。如果我切换到{11}的推荐方言org.hibernate.dialect.Oracle10gDialect
,前一行最终看起来像这样:
registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
现在生成了正确的定义(使用char
代替byte
),这解决了我的问题。