1

Grails サービスで、オブジェクトを mongodb に保存してみます。

Cover saveCover = new Cover()
saveCover.id = url
saveCover.url = url
saveCover.name = name
saveCover.sku = sku
saveCover.price = price

saveCover.save()

カバー ドメインは次のようになります。

class Cover {

    String id
    String name
    String url
    String sku
    String price
}

したがって、URLに基​​づいてカスタムIDを取得したいのですが、保存プロセス中にエラーが発生します:

データストア トランザクションをコミットできませんでした。ネストされた例外は org.grails.datastore.mapping.core.OptimisticLockingException: 編集中に別のユーザーによってインスタンスが更新されました

しかし、セッターを使用せず、コンストラクターですべての値を渡すだけであれば、例外はなくなります。なんで?

4

2 に答える 2

4

ここのドキュメントで報告されているように:

識別子を手動で割り当てる場合は、save メソッドの代わりに insert メソッドを使用する必要があることに注意してください。そうしないと、GORM は、挿入または更新を実行しようとしているかどうかを判断できません。

そのため、id ジェネレーターが割り当てられている場合は、save の代わりに insert メソッドを使用する必要があります

cover.insert(failOnError: true)

次のようにマッピングを定義しない場合:

static mapping = {
    id generator: 'assigned'
}

自動生成された objectId を取得する挿入メソッドを使用します。

"_id" : "5496e904e4b03b155725ebdb"
于 2014-12-21T15:42:57.417 に答える
1

この例外は、ID を新しいモデルに割り当てて保存しようとしたときに発生します。これは、GORM が更新を行う必要があると判断したためです。

この例外が発生する理由

この問題に遭遇したとき、私は grails-mongo プラグインの 1.3.0 を使用していました。これは、grails データストア コア コードの 1.1.9 を使用します。NativeEntryEntityPersister の 847行目 (ish) で例外が生成されることに気付きました。このコードは、データベース内の既存のドメイン オブジェクトを更新します。

その上の 790 行目isUpdateは、更新かどうかを確認するために使用される作成場所です。挿入が強制された場合のみそisInsertfalseままで、オブジェクトに割り当てられた ID を返すため、最終的に true として評価されます。truereadObjectIdentifierisUpdate

例外の修正

791 行目のおかげで&& !isInsert、挿入を強制すると、挿入コードが呼び出され、例外が確実になくなります。ただし、これを行ったとき、割り当てられた ID は保存されず、代わりに生成されたオブジェクト ID が使用されました。これに対する修正は803 行目にあり、ジェネレーターが に設定されているかどうかをチェックしています"assigned"

これを修正するには、次のマッピングを追加できます。

class Cover {
    String id
    String name
    String url
    String sku
    String price
    static mapping = {
        id generator: 'assigned'
    }
}

これの副作用は、新しいカバー ドメイン オブジェクトに常に ID を割り当てる必要があることです。

于 2013-12-09T13:56:36.620 に答える