1

。という名前のmysqlテーブルがありますanto2。の列は1つだけnameですvarchar 100。このテーブルをgrailsドメインクラスにマップしようとしました:

class Anto {

    String grailsName

    static constraints = {
    }

    static mapping = {
        table 'anto2'
        grailsName column: 'name'
    }
}

実行した後run-app、テーブルにさらに2つの列が追加されていることがわかります。

+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| name    | varchar(100) | YES  |     | NULL    |       |
| id      | bigint(20)   | NO   |     | NULL    |       |
| version | bigint(20)   | NO   |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+

このドメインクラスの静的ビューとコントローラーを生成しましたが、保存しようとすると、save()メソッドでエラーが発生します(generate-allコマンドを使用して生成されます)。エラーは次のとおりです。

2012-07-09 23:05:26,391 [http-bio-8080-exec-2] ERROR errors.GrailsExceptionResolver  - SQLException occurred when processing request: [POST] /mysql/anto/save - parameters:
create: Create
Field 'id' doesn't have a default value. Stacktrace follows:
Message: Field 'id' doesn't have a default value
    Line | Method
->> 1073 | createSQLException in com.mysql.jdbc.SQLError
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   3597 | checkErrorPacket   in com.mysql.jdbc.MysqlIO
|   3529 | checkErrorPacket . in     ''
|   1990 | sendCommand        in     ''
|   2151 | sqlQueryDirect . . in     ''
|   2625 | execSQL            in com.mysql.jdbc.ConnectionImpl
|   2119 | executeInternal .  in com.mysql.jdbc.PreparedStatement
|   2415 | executeUpdate      in     ''
|   2333 | executeUpdate . .  in     ''
|   2318 | executeUpdate      in     ''
|    105 | executeUpdate . .  in org.apache.commons.dbcp.DelegatingPreparedStatement
|     25 | save               in mnm.AntoController
|   1110 | runWorker . . . .  in java.util.concurrent.ThreadPoolExecutor
|    603 | run                in java.util.concurrent.ThreadPoolExecutor$Worker
^    722 | run . . . . . . .  in java.lang.Thread

なぜこれが起こるのですか?どこが間違っていたのですか?

4

2 に答える 2

3

IDジェネレーターの種類を指定しない場合、GORMはデータベースのネイティブ戦略を使用します。mysqlをdbとして使用している場合は、IDENTITY戦略を使用してIDを作成して生成します。この戦略では、id列を自動インクリメントする必要があります。

戦略を定義する方が良いと思いますが。SEQUENCE戦略を使用できます。

id column:'id_anto2', generator:'sequence', params:[sequence:'tab_anto2_seq']

次に、データベースに同じ名前のシーケンスを作成します(したがって、Hibernateが自動的に作成したシーケンスを使用する必要はありません)。それはとても簡単で、魅力のように機能します。

また、バージョンフィールドを破棄するには、マッピングブロックにバージョンfalseを挿入します。したがって、次のようになります。

static mapping = {
        table 'anto2'
        id column: 'id_anto2', generator: 'sequence', params: [sequence:'tab_anto2_seq']
        grailsName column: 'name'
        version false
}
于 2012-07-09T20:09:34.330 に答える
0

ID マッピングが欠落しているようです。静的マッピング クロージャに id 参照を追加してみてください。また、これが既存のデータベースである場合は、datasource.groovy の設定方法に応じて、バージョンを false に設定するか、grails がバージョン列を使用してテーブルを変更しようとする場合があります。

    table 'anto2'
    version false
    id column:'anto2_ID'
    grailsName column: 'name'
于 2012-07-09T17:56:21.233 に答える