Reputation: 11
I am using the following:
I have two domain objects that look like this:
class PhoneNumber {
String country
String numberString
static constraints = {
country nullable: false, size: 2..2
numberString nullable: false, blank: false, size: 1..16
}
}
and
class Contact {
String name
static hasMany = [phoneNumber: PhoneNumber]
static embedded = ['phoneNumber']
static constraints = { }
}
I have a controller that looks like this:
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
}
}
When I POST to the controller via:
curl -XPOST "http://localhost:8080/contact" -d "@contact.json"
I get a response of {"id":1}
. However if I add the following line to my Contact and PhoneNumber domain objects:
static mapWith = 'mongo'
I get the following error:
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]
What else needs to be done to get mongodb domain objects marshalled on a POST?
Upvotes: 0
Views: 413
Reputation: 5976
Explicitly define the id
field as an ObjectId
when using MongoDB.
domain/com/example/Book.groovy
package com.example
import org.bson.types.ObjectId
class Book {
ObjectId id
String title
String author
static mapWith = "mongo"
}
BSON IDs are not simple long
numbers — they contain four parts, including a timestamp. When converted to a String
(example: book.id as String
), the ID will be 24 characters long and look something like: "556a7299aa2437211f8e4e73"
See:
https://docs.mongodb.com/manual/reference/method/ObjectId
Upvotes: 1