Grails逆向工程和表/列命名策略

时间:2014-08-06 10:44:41

标签: sql-server spring hibernate grails reverse-engineering

我对Grails很新,但我有Spring 3和Hibernate的强大背景。实际上,我只是在玩它,看看我能为中小型项目提高生产力。 我试图将遗留的SQLServer-Hibernate-Spring-JSP应用程序迁移到Grails,这就是我安装逆向工程插件的原因。虽然很容易让它运行起来,但我现在面临某种命名惯例/策略,其中列名称我不知道如何解决。 我运行插件为我的SQL Server数据库中的单个表生成域类(只是为了尝试),然后运行" generate-all"获取控制器和CRUD视图。到目前为止一切正常。当我运行应用程序并显示所有可用控制器的主视图时,我单击我新生成的控制器,但这会导致我找到一个错误页面,其中显示找不到某个列名称。 请参阅下面生成的域类:

class Documentos {

    String fileName
    Integer fileSize
    byte[] document
    Integer idTipoDocumento
    Boolean visible
    Date dateElaborated
    Date dateApproved
    String state
    String author
    String department
    String scope
    String language
    String codeNumber
    String comments
    Boolean manual
    Boolean hasChecklists

    static mapping = {
        id generator: "assigned"
    }

    static constraints = {
        fileName maxSize: 150
        fileSize nullable: true
        document nullable: true
        idTipoDocumento nullable: true
        visible nullable: true
        dateElaborated nullable: true
        dateApproved nullable: true
        state nullable: true
        author nullable: true
        department nullable: true
        scope nullable: true
        language nullable: true
        codeNumber nullable: true
        comments nullable: true
        manual nullable: true
        hasChecklists nullable: true
    }
}

如果我检查生成的类,一切看起来都很好(除了SQLServer nvarchar类型转换为Serializable而不是String,但我现在可以接受应用手动替换)。 但是,当Grails调用DocumentosController.groovy中的list方法时,会检索到以下错误:

Error |
2014-08-06 11:20:30,711 [http-bio-8080-exec-2] ERROR util.JDBCExceptionReporter  - El nombre de columna 'code_number' no es válido.
Error |
2014-08-06 11:20:30,718 [http-bio-8080-exec-2] ERROR errors.GrailsExceptionResolver  - SQLServerException occurred when processing request: [GET] /IdeaProjects/documentos/index
El nombre de columna 'code_number' no es válido.. Stacktrace follows:
Message: El nombre de columna 'code_number' no es válido.
    Line | Method
->>  216 | makeFromDatabaseError      in com.microsoft.sqlserver.jdbc.SQLServerException
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1515 | getNextResult              in com.microsoft.sqlserver.jdbc.SQLServerStatement
|    404 | doExecutePreparedStatement in com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement
|    350 | doExecute                  in com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd
|   5696 | execute . . . . . . . . .  in com.microsoft.sqlserver.jdbc.TDSCommand
|   1715 | executeCommand             in com.microsoft.sqlserver.jdbc.SQLServerConnection
|    180 | executeCommand . . . . . . in com.microsoft.sqlserver.jdbc.SQLServerStatement
|    155 | executeStatement           in     ''
|    285 | executeQuery . . . . . . . in com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement
|     55 | <init>                     in grails.orm.PagedResultList
|     15 | $tt__index . . . . . . . . in com.DocumentosController
|    200 | doFilter                   in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter . . . . . . . . . in grails.plugin.cache.web.filter.AbstractFilter
|    886 | runTask                    in java.util.concurrent.ThreadPoolExecutor$Worker
|    908 | run . . . . . . . . . . .  in     ''
^    662 | run                        in java.lang.Thread

基本上,它表示&#34; code_number&#34;找不到列,但正如您在域类中看到的那样,实际的列名是codeNumber。我不明白为什么Grails试图访问名为&#34; code_number&#34;的列。但我想这可能与命名策略有关,正如我在Grails site中看到的那样。我猜这个命名策略很好,当你不进行逆向工程时,但我不知道如何解决这个特殊情况。显然,我不想更改所有数据库列名。

有什么想法吗?

谢谢!

修改

好的,我已经能够解决问题了,虽然我对这个问题并不满意。我在生成的类中添加了一些显式映射,这解决了问题。最后一堂课应该是这个:

class Documentos {

    String fileName
    Integer fileSize
    byte[] document
    Integer idTipoDocumento
    Boolean visible
    Date dateElaborated
    Date dateApproved
    String state
    String author
    String department
    String scope
    String language
    String codeNumber
    String version
    String comments
    Boolean manual
    Boolean hasChecklists

    static mapping = {
        id generator: "assigned"
        fileName column: "fileName", sqlType: "varchar", length: 150
        fileSize column: "fileSize", sqlType: "int"
        idTipoDocumento column: "idTipoDocumento", sqlType: "int"
        codeNumber column: "codeNumber", sqlType: "nvarchar", length: 4
        version column: "version", sqlType: "nvarchar", length: 4
        dateApproved column: "dateApproved", sqlType: "smalldatetime"
        dateElaborated column: "dateElaborated", sqlType: "smalldatetime"
        hasChecklists column: "hasChecklists", sqlType: "bit"
    }

    static constraints = {
        fileName maxSize: 150
        fileSize nullable: true
        document nullable: true
        idTipoDocumento nullable: true
        visible nullable: true
        dateElaborated nullable: true
        dateApproved nullable: true
        state nullable: true
        author nullable: true
        department nullable: true
        scope nullable: true
        language nullable: true
        codeNumber nullable: true
        comments nullable: true
        manual nullable: true
        hasChecklists nullable: true
    }
}

你可以想象,这不是我对Grails的期望。我希望从逆向工程过程中获得一个有效的域类,但我得到一个我仍然需要修改的类。我不想为我的数据库中的其他100个表执行此操作.......有没有人知道我是否可以添加某种配置以避免所有这些&#34;手册&#34;映射?

谢谢!

1 个答案:

答案 0 :(得分:0)

无论您是从DB生成域类,还是从DB生成域类,都必须保持一致。由于您的Documentos域类具有名为codeNumber的属性,因此documentos数据库表必须具有名为code_number的列。

在您的评论中,您表示此列不存在,因此我猜这是导致错误的原因。