使用 TEXT 字段将 Grails 域类映射到旧数据库时出现问题

发布于 2024-11-18 17:38:31 字数 2451 浏览 5 评论 0 原文

我正在尝试使用 Grails 1.3.7 和 MySQL 5.1.56 为遗留数据库构建一组域类。我在 BuildConfig.groovy 文件中将 MySQL 连接器指定为“mysql:mysql-connector-java:5.1.13”。

数据库模式有一个名为“abstract”、类型为 TEXT 的字段。

我在类中声明相应的属性,如下所示(为清楚起见,仅显示相关部分):

class Paper {
    String abstractText

    static mapping = {
        table 'papers'
        abstractText column: 'abstract'
    }

    static constraints = {
        abstractText(nullable: false, maxSize: 65535)
    }
}

当我运行集成测试时,出现以下错误:

Wrong column type in citeseerx.papers for column abstract. 
Found: text, expected: longtext

如果我将声明更改为,

    static mapping = {
        abstractText column: 'abstract', type: 'text'
    }

则会出现相同的错误。如果我将类型设置为“longtext”,我会

Could not determine type for: longtext, at table: papers, 
for columns: [org.hibernate.mapping.Column(abstract)]

看到一个看似相关的讨论 Hibernate bug,我想知道是否有解决方法,或者对具有 TEXT 字段的模式进行建模的其他方法。

谢谢,

Gene

已编辑:这是相关的 DataSource.groovy 片段:

dataSource {
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://mydbhost:3306/mydb"
    username = "u"
    password = "p"
    dbCreate = 'validate'
    //dialect = org.hibernate.dialect.MySQL5Dialect
    dialect = com.fxpal.citeseer.mysql.MyMySQLDialect
    println("Setting dialog = ${dialect}")  
}

hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = true
    cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}

已编辑(2):这是自定义 Dialect 类,如 @Stefan 的答案所建议:

import java.sql.Types;

/**
 * An An extension to the SQL dialect for MySQL 5.1 to handle TEXT.
 *
 * @author Gene Golovchinsky
 */
public class MyMySQLDialect extends org.hibernate.dialect.MySQLDialect {

    public MyMySQLDialect() {
        super();
        System.out.println("MyMySQLDialect: created new instance");
    }

    protected void registerVarcharTypes() {
        System.out.println("MyMySQLDialect: RegisteringVarcharTypes");
        registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
        registerColumnType( Types.VARCHAR, 65535, "text" );
        registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
        registerColumnType( Types.LONGVARCHAR, "longtext" );
    }
}

I am trying to build a set of domain classes for a legacy database using Grails 1.3.7 and MySQL 5.1.56. I am specifying the MySQL connector in the BuildConfig.groovy file as 'mysql:mysql-connector-java:5.1.13'.

The database schema has a field named 'abstract' of type TEXT.

I am declaring the corresponding property in my class as follows (only relevant parts shown for clarity):

class Paper {
    String abstractText

    static mapping = {
        table 'papers'
        abstractText column: 'abstract'
    }

    static constraints = {
        abstractText(nullable: false, maxSize: 65535)
    }
}

When I run my integration test, I get the following error:

Wrong column type in citeseerx.papers for column abstract. 
Found: text, expected: longtext

If I change the declaration to be

    static mapping = {
        abstractText column: 'abstract', type: 'text'
    }

I get the same error. If I set the type to 'longtext', I get

Could not determine type for: longtext, at table: papers, 
for columns: [org.hibernate.mapping.Column(abstract)]

I saw a discussion of a seemingly-related Hibernate bug, and I am wondering if there is a work-around for it, or some other way of modeling schemas that have TEXT fields.

Thanks,

Gene

EDITED: Here is the relevant DataSource.groovy snippet:

dataSource {
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://mydbhost:3306/mydb"
    username = "u"
    password = "p"
    dbCreate = 'validate'
    //dialect = org.hibernate.dialect.MySQL5Dialect
    dialect = com.fxpal.citeseer.mysql.MyMySQLDialect
    println("Setting dialog = ${dialect}")  
}

hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = true
    cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}

EDITED(2): Here is the Custom Dialect class, as suggested by @Stefan's answer:

import java.sql.Types;

/**
 * An An extension to the SQL dialect for MySQL 5.1 to handle TEXT.
 *
 * @author Gene Golovchinsky
 */
public class MyMySQLDialect extends org.hibernate.dialect.MySQLDialect {

    public MyMySQLDialect() {
        super();
        System.out.println("MyMySQLDialect: created new instance");
    }

    protected void registerVarcharTypes() {
        System.out.println("MyMySQLDialect: RegisteringVarcharTypes");
        registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
        registerColumnType( Types.VARCHAR, 65535, "text" );
        registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
        registerColumnType( Types.LONGVARCHAR, "longtext" );
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人间☆小暴躁 2024-11-25 17:38:31

您可能可以从 https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java 并更改“文本”的映射。然后使用“dialect =”设置将新方言应用到 Datasource.groovy。

You could probably derive a custom dialect from https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java and change the mapping for 'text'. Then apply the new dialect to Datasource.groovy using the "dialect = " setting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文