2016-10-19 35 views
0

我已經部署了與DB設置一個JBoss(5.2)服務器爲Oracle DB一個Grails(2.2.4)應用:的SQLException Grails中保存()方法

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

我也有兩個域對象:

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 
} 

當使用Hibernate的自己H2 DB和測試當地既Grails的運行程序Grails的運行戰爭這項工作很好,但與Oracle數據庫集成和部署到JBoss服務器後,我收到以下錯誤:

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 

任何人有一個想法這裏發生了什麼問題?

+0

該錯誤通常是因爲沒有提供'?'的值。我不知道爲什麼它會出現在其他數據庫中,而不是在部署數據庫時出現,但這就是我將開始研究的內容。 – Gregg

+0

我想,但因爲這個錯誤是由某個方法調用** save()**方法跟蹤造成的,我不知道如何開始調試它? –

+0

您可以記錄綁定值。閱讀這篇文章,看看它是否有幫助:http://margotskapacs.com/2013/01/log-and-debug-gorm/ – Gregg

回答

0

我設法解決這個問題。我不得不放置unique attributt在one-to-one映射的親子關係,因爲這:

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 
    } 
} 

真的不知道爲什麼,但它的工作。

+0

它的工作原理是因爲你確實無法對hasOne關係強制執行一個唯一的約束。我只是好奇這是如何與我的答案不同。我已經提供了更多解決方案。 – elixir

+0

您錯過了將「唯一」約束添加到其他域類。沒有它,它看起來不像表'B'在列'a'上獲得'唯一'約束,理論上多個'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

嘿,我想我可以簡化,但這些修改仍然會保留級聯刪除和實際的「一對一」關係? –

+0

只要您的belongsTo關係被正確定義,級聯就可以工作。 – elixir