Grails 逆向工程在脚手架时显示无效列

Grails reverse engineering shows invalid column when scaffolding

我看到很多 post 与 Hibernate 和逆向工程相关。但是我找不到与此相关的任何内容。抱歉,如果我重复已经回答并关闭,请 post URL 如果有人知道它。

我的问题是当我使用脚手架时使用逆向工程时 Grails 显示无效列。逆向工程根据现有数据库创建域 class。因此,作为逆向工程的一部分,我不想更改数据库或自动创建的域 class 中的任何内容。除了编辑域 class 或数据库列之外,必须有一些解决方案。

错误:

....Error 
|
2015-02-04 07:52:41,004 [http-bio-8080-exec-3] ERROR util.JDBCExceptionReporter  - Invalid column name 'category_id'.
Error |
2015-02-04 07:52:41,132 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver  - SQLServerException occurred when processing request: [GET] /reverseEng/expense/index
Invalid column name 'category_id'.. Stacktrace follows:
Message: Invalid column name 'category_id'.
    Line | Method
->>  197 | makeFromDatabaseError      in com.microsoft.sqlserver.jdbc.SQLServerException
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1493 | getNextResult              in com.microsoft.sqlserver.jdbc.SQLServerStatement
|    390 | doExecutePreparedStatement in com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement
|    340 | doExecute                  in com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd
|   4575 | execute . . . . . . . . .  in com.microsoft.sqlserver.jdbc.TDSCommand
|   1400 | executeCommand             in com.microsoft.sqlserver.jdbc.SQLServerConnection
|    179 | executeCommand . . . . . . in com.microsoft.sqlserver.jdbc.SQLServerStatement

代码:

Used the plugin : compile ":db-reverse-engineer:0.5.1"
Changed the hibernate to   runtime ":hibernate:3.6.10.18"  instead of 4

域class- 类别

package com.reverseEng

class Category {

    BigDecimal intCatId
    String strCatName

    static hasMany = [expenses: Expense]

    static mapping = {
        id name: "intCatId", generator: "assigned"
        version false
    }
}

域class费用

package com.reverseEng

class Expense {

    Double fltAmt
    Date dtDate
    Category category

    static belongsTo = [Category]

    static mapping = {
        id column: "intTranId", generator: "assigned"
        version false
    }
}

控制器:

package com.reverseEng

class ExpenseController {

    /*def index() { }*/
    static scaffold=Expense
}

类别控制器:

package com.reverseEng

class CategoryController {

   /* def index() { }*/
    static scaffold=Category
}

数据库结构:MSSQL

table 类别:

intCatId numeric(19,0) Autoincrement Primary key
strCatName varchar

table 费用:

intTranId int Autoincrement primary key
fltAmt Float
dtDate date
intCatId Foreign key to the Category table.

Config.grrovy 更新为

grails.plugin.reveng.packageName = 'com.reverseEng'
grails.plugin.reveng.includeTables = ['category','expense']

执行了grails db-reverse-engineer然后执行了run-app.

永远不要相信生成的代码。假设这个插件和任何其他为您生成代码的插件充其量只是一个不错的节省时间,但无论您是手动输入每个字符还是从生成的代码开始并修复它,最终结果都必须是您理解和信任的工作代码。

这里的核心问题是你在Expenseclass中有一个名为category的属性但是它没有映射配置,所以它使用默认命名将 class 和 属性 名称转换为 table 和列名称的方法。由于它是对另一个持久性 class 的引用,其列名是通过将驼峰式 属性 名称(在本例中没有内部大写字符)转换为下划线分隔的列名并添加_id,所以是 category_id。但是列名是 intCatId,因此您需要将其添加到 mapping 块。

还有一些其他问题,我会利用这个机会使用合理的变量名,而不是使用数据库中使用的冗余前缀 VB 式命名。如果您的变量名描述了它们的作用,则它们很少需要前缀或其他提示。

对于 Category class 我会更改名称 属性 并添加一个 column 映射,并删除显式主键 属性 之类的在 Expense 中,只需指定其列名:

class Category {

    String name

    static hasMany = [expenses: Expense]

    static mapping = {
        id column: "intCatId", generator: "assigned"
        name column: 'strCatName'
        version false
    }
}

Expense 中为 category 添加一个映射以指定 intCatId 而不是 category_id,就像 Category 我会制作日期和人类可读的数量属性(并将显式 category 字段与 belongsTo 映射结合起来,因为这两种方法具有相同的效果):

class Expense {

    Double amount
    Date date

    static belongsTo = [category: Category]

    static mapping = {
        id column: "intTranId", generator: "assigned"
        amount column: 'fltAmt'
        date column: 'dtDate'
        category column: 'intCatId'
        version false
    }
}