grails 3 mongodb: метод класса [] использовался вне приложения Grails

Я использую следующее:

  • Версия Grails: 3.0.1
  • Крутая версия: 2.4.3
  • Версия JVM: 1.8.0_05
  • монгодб: 3.0.3

У меня есть два объекта домена, которые выглядят так:

class PhoneNumber {
    String country
    String numberString

    static constraints = {
        country nullable: false, size: 2..2
        numberString nullable: false, blank: false, size: 1..16
    }
}

а также

class Contact {
    String name

    static hasMany = [phoneNumber: PhoneNumber]

    static embedded = ['phoneNumber']
    static constraints = { }
}

У меня есть контроллер, который выглядит так:

class ContactController extends RestfulController {
    static responseFormats = ['json', 'xml']

    ContactController() { super(Contact) }


    @Transactional
    def save(Contact contact) {
        println contact
        response.status = 201
        def result = [:]
        result.id = 1
        render result as JSON
    }
}

Когда я POST на контроллер через:

curl -XPOST "http://localhost:8080/contact" -d "@contact.json"

Я получаю ответ {"id":1}. Однако, если я добавлю следующую строку в свои объекты домена Contact и PhoneNumber:

static mapWith = 'mongo'

Я получаю следующую ошибку:

ERROR org.grails.web.errors.GrailsExceptionResolver - IllegalStateException occurred when processing request: [POST] /contact - parameters:
{"id":null,"name":"Full Name","phoneNumber":[{"country":"ca","numberString":"18095551212"},{"country":"ca","numberString":"16135551212"}]}: 
Method on class [xxx.Contact] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.. Stacktrace follows:
    java.lang.IllegalStateException: Method on class [demo.Contact] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
at  grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:93) ~[grails-core-3.0.1.jar:3.0.1]
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:90) ~[grails-core-3.0.1.jar:3.0.1]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_05]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_05]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_05]

Что еще нужно сделать, чтобы объекты домена mongodb были маршалированы в POST?


person 316    schedule 27.04.2015    source источник


Ответы (1)


Явно определите поле id как ObjectId при использовании MongoDB.

домен/com/example/Book.groovy

package com.example

import org.bson.types.ObjectId

class Book {

   ObjectId id
   String   title
   String   author

   static mapWith = "mongo"

}

Идентификаторы BSON — это не простые long числа, они состоят из четырех частей, включая метку времени. При преобразовании в String (пример: book.id as String) идентификатор будет состоять из 24 символов и выглядеть примерно так: "556a7299aa2437211f8e4e73"

См.:
https://docs.mongodb.com/manual/reference/method/ObjectId

person Dem Pilafian    schedule 06.06.2015