2011-07-28 8 views
3

我正在嘗試爲Mongo的低級API使用GORM進行安全插入。如何使用GORM爲Mongo的低級API安全插入?

我曾經在一個乾淨的Grails項目重現的問題,就像如下:

  1. 創建一個新的Grails工程
  2. 卸載Hibernate插件
  3. 安裝了蒙戈插件格姆
  4. 創建控制器有以下動作

    import com.mongodb.* 
    
    class TestController { 
    
        def mongo 
    
        def index = { 
    
         def database = mongo.getDB("ExampleDatabase") 
         def collection = database.getCollection("ExampleCollection") 
    
         def document = new BasicDBObject(); 
         document.put("key", "value") 
    
         collection.insert(document, WriteConcern.SAFE) 
    
         render "" 
    
        } 
    } 
    
  5. 當射擊的動作,下面的異常被拋出:

    2011-07-27 12:53:03,161 [http-8080-1] ERROR errors.GrailsExceptionResolver - Exception occurred when processing request: [GET] /WriteConcern.SAFE-test/test/index 
    Stacktrace follows: 
    groovy.lang.MissingPropertyException: No such property: value for class: com.mongodb.WriteConcern 
        at com.gmongo.internal.Patcher$__converAllCharSeqToString_closure2.doCall(Patcher.groovy:81) 
        at com.gmongo.internal.Patcher._converAllCharSeqToString(Patcher.groovy:80) 
        at com.gmongo.internal.Patcher$_converAllCharSeqToString.callStatic(Unknown Source) 
        at com.gmongo.internal.Patcher$_converAllCharSeqToString.callStatic(Unknown Source) 
        at com.gmongo.internal.Patcher._convert(Patcher.groovy:69) 
        at com.gmongo.internal.Patcher$_convert.callStatic(Unknown Source) 
        at com.gmongo.internal.Patcher$__patchInternal_closure1.doCall(Patcher.groovy:31) 
        at writeconcern.safe.test.TestController$_closure1.doCall(TestController.groovy:17) 
        at writeconcern.safe.test.TestController$_closure1.doCall(TestController.groovy) 
        at java.lang.Thread.run(Thread.java:680) 
    
  6. 如果我改變使用蒙戈的Java API如下動作:

    def index = { 
    
        def database = new Mongo().getDB("ExampleDatabase") 
        def collection = database.getCollection("ExampleCollection") 
    
        def document = new BasicDBObject(); 
        document.put("key", "value") 
    
        collection.insert(document, WriteConcern.SAFE) 
    
        render "" 
    
    } 
    
  7. 現在,它的工作原理和文檔按預期堅持到Mongo數據庫。

我的問題是:這是與GMongo包裝一個錯誤,或者那麼應該如何安全地寫入使用低級別的API做了什麼?

回答

4

出現這種情況是由於GMongo庫及其如何修補DBCollection對象以處理將Map對象傳遞給insert方法並將其轉換。它假定insert方法的所有參數都是Map對象,然後將嘗試從Map.Entry獲取value屬性。

看着source of Patcher.groovy from GMongo library你會看到_convert()這個功能試圖做到這一點。它看起來像Github項目的一個分支,對參數進行類型檢查(要麼檢查它是否爲WriteConcern,要麼在檢查傳遞到_converAllCharSeqToString之前檢查它是否實際上是)是必要的。

編輯:

我在Github上創建了一個pull request爲適當的代碼更改,但與Groovy的所有的東西,貼敷類也有幫助。您可以「打補丁」的WriteConcern類在BootStrap.groovygetValue方法,這將允許你通過參數:

def init = { servletContext -> 
    com.mongodb.WriteConcern.metaClass.getValue = { null } 
} 
+0

感謝您的解釋。 Monkeypatching WriteConcern類像你說的很好。 – AndrewW

相關問題