Hibernate如何映射SQL数据类型nvarchar(max)?

16

我的SQL-2005数据库中有一个列,原来是 varchar(max) 类型,现在改成了 nvarchar(max) 类型。

现在我需要更新我的 Hibernate 映射文件以反映这个更改,下面是之前的代码:

<element type="text" column="Value"/>

当我尝试运行应用程序时,出现以下错误:

org.hibernate.HibernateException: [Table] 表的值列类型不正确。找到的是 ntext,期望的是 text

我应该在 'type' 属性中放入什么内容才能将该列正确地映射为 nvarchar(max) 类型?

我尝试将类型设置为 ntext,但 Hibernate 不认识这个类型。我尝试将类型设置为 string,但它将其视为 text 类型。

5个回答

21

对我有用的方法是将实际列定义放在@Column注释中:

    @Column(name="requestXml", columnDefinition = "ntext")
private String request;

3
这对我也有效。我在数据库中使用nvarchar(max),并且"@Column(name="colName", columnDefinition = "nvarchar")"修复了它。 - petrsyn

11

通过Hibernate提供的 @Nationalized 注解,可以修复字符数据类型的问题,例如国际化变体(NVARCHAR,NCHAR,NCLOB等)。


8

Tremend Tech Blog 找到了答案。 您需要编写自己的 SQLServerDialect 类,大致如下:

public class SQLServerNativeDialect extends SQLServerDialect {
     public SQLServerNativeDialect() {
         super();
         registerColumnType(Types.VARCHAR, "nvarchar($l)");
         registerColumnType(Types.CLOB, "nvarchar(max)");
     }

    public String getTypeName(int code, int length, int precision, int scale) throws HibernateException {
        if(code != 2005) {
            return super.getTypeName(code, length, precision, scale);
        } else {
            return "ntext";
        }
    }
}

这个类将Hibernate的类型映射到SQL类型,因此该类将把nvarchar(max) SQL数据类型映射到Hibernate的CLOB数据类型。
当Hibernate使用代码2005询问数据类型(看起来像是nvarchar(max)数据类型)时,getTypeName方法用于返回"ntext"。
最后,您需要将Hibernate持久化方言更改为这个新的SQLServerDialect类,它允许Hibernate将数据类型转换为SQL数据类型。

3
为什么你还注册了列类型COLB?而nvarchar($1)中的$1代表什么意思?(注意:为了尽可能地保持原文意思,本翻译采用了与中文语序较为接近的英语语序) - vishnu viswanath
1
这是很久以前的事情,我有些记不清了,但registerColumnType()函数将SQL类型映射到Hibernate类型。$l(L而不是#1)是一个匹配模式,它代表nvarchar列的长度。如果nvarchar列有定义的长度,则会映射为VARCHAR类型。如果nvarchar列具有最大长度,则会映射为CLOB类型。 - ampersandre
1
请注意,对于SQL Server 2014,我必须在上面的代码中删除重写的方法getTypeName!! - vikingsteve

0

使用 @Nationalized 并将 length = Integer.MAX_VALUE 设置为解决 NVARCHAR(MAX) 问题的方法。

实体类应该像这样:

    @Nationalized
    @Column(length = Integer.MAX_VALUE)
    private String nvarcharMax;

更多细节请查看文档这里


0

我认为这是 registerColumnType(Types.VARCHAR, "nvarchar($l)"); // 这里的 l 指的是长度,而不是数字 1。


例如,registerColumnType(Types.NVARCHAR, 4000, "nvarchar($1)") 中的 $1 表示长度。 - Eyal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接