使用 TEXT 字段将 Grails 域类映射到遗留数据库的问题

Posted

技术标签:

【中文标题】使用 TEXT 字段将 Grails 域类映射到遗留数据库的问题【英文标题】:Problem mapping Grails Domain class to legacy database with TEXT field 【发布时间】:2011-09-29 02:09:07 【问题描述】:

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

数据库架构有一个名为“抽象”的 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”,我会得到 ​​p>

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

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

谢谢,

基因

已编辑:这是相关的 DataSource.groovy sn-p:

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):这是自定义 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" );
    

【问题讨论】:

【参考方案1】:

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

【讨论】:

我试图通过在 DataSource.groovy dataSource 闭包中设置 dialect 属性来更改方言,但它似乎没有被实例化。 (我在构造函数里放了一条print语句,在stack trace之前看不到对应的输出。)我也试过把dialect设置为MySQL5Dialect,最后把hibernate的日志级别设置为trace,就产生了一堆“Binding”财产”声明,但没有任何迹象表明错误。我还应该尝试什么以确保尊重方言设置? 能否请您发布 datasources.groovy sn-p? 我将它添加到我的问题中。感谢您的帮助! 我不确定,但这可能是一个类加载问题,我假设找不到给定的方言类。为了验证假设,您能否在类名中打错字。 部分问题是我需要在 IDE 中清理项目;显然 grails 的 clean 并没有冲洗所有东西。

以上是关于使用 TEXT 字段将 Grails 域类映射到遗留数据库的问题的主要内容,如果未能解决你的问题,请参考以下文章

向 Grails 域类添加字段?

如何将 Grails 域类映射到 DTO?

grails域类中的时间字段

在 Grails 中映射遗留数据库表时避免表更改?

更新 Grails 中父域类中的“lastUpdated”字段

如何从 Grails 控制器和视图外部引用 Grails 域类字段?