2016-10-19 9 views
0

私は、Oracle DB用DBのセットアップとJBossの(5.2)サーバーに配備のGrails(2.2.4)アプリケーションました:のSQLExceptionのGrailsでsave()メソッド

datasource { 
    dbCreate = 'update' 
    jndiName = 'java:XXX 
} 

を私はまた、2つのドメインオブジェクトを持っています:

class A { 
    def name 
    static hasOne = [b:B] 
    static constraints = { 
     b unique: true 
     name unique: true 
    } 
} 

class B { 
    A a 
    static belongsTo = [A] 
} 

そして最後のインスタンスを作成/検索するためのサービス:

A createA(String name) { 
    def a = A.findByName(name) 
    if(!a) { 
     a = new A(name: name) 
     a.b = new B(a: a) 
     a.save() <-- This causes the ERROR. Tried a.save(flush:true), a.save(failOnError:true) and a.save(flush:true, failOnError:true) 
    } 
    return a 
} 

休止状態独自H2 DBを使用して

Hibernate operation: could not execute query; uncategorized SQLException for SQL [ 
    select this_.id as id1_0_, this_.version as version1_0_, this_.name as name1_0_ 
    from a this_ 
    where this_.id=?]; 
SQL state [99999]; error code [17041]; 
Missing IN or OUT parameter at index:: 1; 
nested exception is java.sql.SQLException: Missing IN or OUT parameter at index:: 1 

誰もがアイデアを得た:両方GrailsのでローカルテストするGrailsのにこの作品の罰金を戦争で実行しますが、Oracle DBとの統合とJBossサーバーにデプロイした後、私は次のエラーを取得するアプリを実行します何がここで間違っているの?

+0

エラーは一般に '?'の値が提供されなかったためです。私はそれが他のDBのためにそこにあり、あなたがそれを配備したときではない理由を知らないが、それは私が調べ始めるだろう。 – Gregg

+0

私は考えましたが、このエラーは何とか** save()**メソッドのトレースを呼び出すことによって発生したので、デバッグを開始する方法がわかりません。 –

+0

バインド値を記録できます。この記事を読んで、役立つかどうかを確認してください:http://margotskapacs.com/2013/01/log-and-debug-gorm/ – Gregg

答えて

0

私は問題を解決できました。なぜ

class A { 
    def name 
    static hasOne = [b:B] 
    static constraints = { 
     // b unique: true <-- REMOVED 
     name unique: true 
    } 
} 

class B { 
    A a 
    static belongsTo = [A] 
    static constraints = { 
     a unique: true // <-- ADDED 
    } 
} 

本当にわからないが、それは働いていた:私はこのようone-to-oneマッピングの親子関係にunique attributtを配置しなければなりませんでした。

+0

これは、実際にはhasOne関係に一意の制約を適用できないために機能しました。私はちょうどこれが私とは異なるこの答えであるかどうか不思議です。私はすでにソリューションとそれ以上を提供していました。 – elixir

+0

他のドメインクラスに 'unique'制約を追加していませんでした。それがなければ、テーブル 'B'は列' a'に 'unique'制約を与え、理論的には複数の' B'インスタンスが 'A'の同じインスタンスを指すように見えません。おもう?これを見てください:[link](http://docs.grails.org/2.2.4/ref/Domain%20Classes/hasOne.html) –

1

ドメインクラスを変更できることを考慮して、ドメインクラスを次のように変更します。あなたのサービスで

class A { 
    def name 
    static hasOne = [b:B] 
    static constraints = { 
     //b unique: true // try commenting this line out 
     name unique: true 
    } 
} 

class B { 
    A a 
    // static belongsTo = [A] // I don't think you need this. 
} 

A createA(String name) { 
    def a = A.findByName(name) 
    if(!a) { 
     a = new A(name: name).save(flush:true, failOnError:true) 
     //a.b = new B(a: a) // this feels going around in circles. 
     new B(a: a).save(flush:true, failOnError:true) 

     // you may only need one save() and the changes will cascade. 
     //I will leave that upto you which save() cascades and which one doesn't. 
    } 
    return a 
} 

また、あなたはあなたのロジックを簡素化するために、このhttp://docs.grails.org/2.3.1/ref/Domain%20Classes/findOrCreateBy.htmlに見ることができます。

+0

ねえ、私は単純化できると思うけど、これらの変更はまだ削除と実際の「1対1」の関係でカスケードを維持しますか? –

+0

あなたのbelongsTo関係が適切に定義されている限り、カスケードが機能するはずです。 – elixir

関連する問題