I'm using MongoDB exclusively with a Grails REST app and the domain shown below. This respond call fails:
#Secured(['permitAll'])
def index() {
respond Person.list()
}
with the error
ERROR errors.GrailsExceptionResolver - IllegalAccessException occurred when processing request: [GET] /teesheet/person
Class org.codehaus.groovy.grails.web.converters.marshaller.json.GroovyBeanMarshaller can not access a member of class java.util.Collections$UnmodifiableCollection with modifiers "public". Stacktrace follows:
Message: Class org.codehaus.groovy.grails.web.converters.marshaller.json.GroovyBeanMarshaller can not access a member of class java.util.Collections$UnmodifiableCollection with modifiers "public"
Attempting to convert the collection to JSON also fails with the same error.
def personList = Person.list() as JSON
The low level API works.
package com.tworks.teesheet
import grails.rest.Resource
class Person {
String name
String firstName
String lastName
String email
User userPerson
TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles")
Date dateCreated = new Date()
Date dateModified = new Date()
}
Assuming you're using Mongo for Grails plugin, you need #Entity for domain classes...
import grails.persistence.Entity
#Entity
class Person {
static mapWith = "mongo"
String name
String firstName
String lastName
String email
}
I added mapWith="mongo" since I wasn't sure if you're using the hibernate plugin alongside the mongo plugin; if you're not, remove hibernate, otherwise, it may interfere.
I'm currently using the low level calls to iterate using the cursor but it seems like the respond Person.list() should work. This code is working:
def cursor = Person.collection.find()
def items = []
try {
while (cursor.hasNext()) {
items << com.mongodb.util.JSON.serialize(cursor.next())
}
} finally {
cursor.close()
}
log.info("items: ${items}")
render items
Related
Hi I am just trying out grails and trying to learn more on domain class. I have two simple domain classes:
Domain Class 1
package grailtest
class Person {
String firstName
String lastName
int age
String email
static constraints = {
}
}
Domain Class 2
package grailtest
class Customer {
String customerId
Person personInCharge
static constraints = {
}
}
When I do a run-app, I can only see
grailtest.Person : 1
as the Person. How can I default it to a particular value, for instance firstName + lastName, to make the application more user friendly?
in the domain override toString method to what you wanted to be display. restart the app
You can use #ToString in case you want an elaborative way of logging or printing in standard out.
import groovy.transform.ToString
#ToString(includeNames=true, includeFields=true)
class Person {
String firstName
String lastName
int age
String email
}
For example,
def person = new Person(firstName: 'Test', lastName: 'hola',
age: 10, email: 'abc#xyz.com')
would give
Person(firstName:Test, lastName:hola, age:10, email:abc#xyz.com)
Find the view where it displays grailstest.Person: 1 and update it to:
${personInstance.firstName} ${personInstance.lastName}
By default this view should be in "views/person"
You put this code in the view .gsp
${personInstance?.firstname} ${personInstance?.lastname}
I am trying to use this super good plugin:
https://github.com/robfletcher/grails-gson/blob/master/test/apps/gson-test/grails-app/controllers/grails/plugin/gson/test/AlbumController.groovy
because the default GRAILS JSON does not expand the related items.
However when I try it, it fails.
Now, when i do this, it works:
def levelJson() {
render ToolType.list(params) as JSON
}
This fails:
def levelJson() {
render ToolType.list(params) as GSON
}
Error:
ERROR errors.GrailsExceptionResolver - UnsupportedOperationException occurred when processing request: [GET] /authtools/toolType/levelJson
Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?. Stacktrace follows:
Message: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
Classes:
class Artist {
String name
static hasMany = [albums: Album]
}
class Album {
String title
static belongsTo = Artist
}
The solution as dmahapatro pointed out was to modify the data class belongsTo
Before (not working):
class Album {
String title
static belongsTo = Artist
}
After (working):
class Album {
String title
static belongsTo = [artist: Artist]
}
I'm new to Grails and study it via InfoQ's "Getting Started With Grails" book.
Running through it I've faced a problem with the BootStrap.groovy file:
I've edited it as the book says.
Run-app it - and the data I've entered into BootStrap.groovy has been shown.
I've updated the bootstrapping values but they are not changed.
No errors are shown in the console.
What I've tried:
exchanging def's places;
set Runner's class value to nullables;
changed .save(failOnError:true) to .save(flush:true).
Even after I've changed the Race class' bootstrapping values it looks like it hasn't been changed.
Looks like the value is taken from somewhere else than the BootStrap.groovy?
I use Grails 2.2.1 with a PostgreSQL DB.
The classes' code is below:
package racetrack
class Runner {
static constraints = {
firstName(blank:false)
lastName(blank:false)
dateOfBirth(nullable:true)
gender(inList:["M","F"])
address(nullable:true)
city(nullable:true)
state(nullable:true)
zipcode(nullable:true)
email(email:true)
}
static hasMany = [registrations:Registration]
/*static mapping = {
sort "email"
}*/
String firstName
String lastName
Date dateOfBirth
String gender
String address
String city
String state
String zipcode
String email
String toString(){
"${firstName} ${lastName} (${email})"
}
}
and
package racetrack
class BootStrap {
def init = { servletContext ->
def begun = new Runner(firstName:"Marathon",
lastName:"Runner",
dateOfBirth:"",
gender:"M",
address:"",
city:"",
state:"",
zipcode:"",
email:"me#me.ru"
)
begun.save(flush:true)
def zabeg = new Race(name:"Run SPB",
startDate:new Date() + 360*30,
city:"Moscow",
state:"Moscow",
cost:10.0,
distance:42.0,
maxRunners:10)
zabeg.save(flush:true)
}
def destroy = {
}
}
EDIT: could this be happening due to any generate-* scripts been run?
Race.groovy:
package racetrack
class Race {
static hasMany = [registrations:Registration]
String name
Date startDate
String city
String state
BigDecimal distance
BigDecimal cost
Integer maxRunners
static constraints = {
name(blank:false, maxSize:50)
startDate(validator: {
return (it >= new Date())
}
)
city()
state(inList:["Moscow", "Volgograd", "SPb", "NN"])
distance(min:0.0)
cost(min:0.0, max:100.0)
maxRunners(min:0, max:100000)
}
static mapping = {
sort "startDate"
}
BigDecimal inMiles(){
return distance*0.6214
}
String toString(){
return "${name}, ${startDate.format('MM/dd/yyyy')}"
}
}
BootStrap should be in grails-app/conf instead. Refer this.
Try to print the errors of the new instance you save by adding
print begun.errors
See if somethings comes up.
You need to remove
def index() { }
from the controllers.
I had the same issue. Now it is fixed.
Having issues with BootStrap.groovy loading development data. Prior it had always loaded data, but now has stopped throwing the below error when running grails run-app.
Message: Validation Error(s) occurred during save():
- Field error in object 'spotlight.content.Profile' on field 'portfolio': rejected value [null];
My 2 models are as follows;
class Portfolio {
Profile profile
String portfolioName
String portdescrip
Integer portpublished
Date dateCreated
Date lastUpdated
AND
class Profile {
static belongsTo = [portfolio: Portfolio]
String portfoliohtml
String portfolioEmail
String portfoliocc
String portfolioAdmin
String portfolioFilestore
String portfolioColor
String bugzillaproduct
String bugzillacomponent
String rtqueue
String teamqueueemail
String etherpadurl
Integer siteupload
Date dateCreated
Date lastUpdated
Within the BootStrap.groovy file I have the following;
import java.util.Date;
import spotlight.content.Profile
import spotlight.content.Portfolio
class BootStrap {
def init = { servletContext ->
def profile = new Profile(portfoliohtml:"No",
portfolioEmail: "ian#ian.com",
portfolioAdmin:"Ian Neilsen",
bugzillaproduct:"bz prod name",
bugzillacomponent:"comp name",
siteupload:1,
portfoliocc: "ian#ian.com",
portfolioColor:"red",
portfolioFilestore:"blah",
rtqueue:"queue name",
teamqueueemail:"ian#ian.com",
etherpadurl:"http://url.com",
).save(failOnError: true)
def portfolio = new Portfolio(portfolioName:"Portfolio 1",
portdescrip:"portfolio descrition field",
portpublished:1,
portfolio:profile).save(failOnError: true)
}
I have tried every incarnation of adding my profile object to the portfolio object without any luck. As I said previously this worked and has now stopped throwing the null error.
has got me stumped any ideas?
cheers
It looks like you have several mistakes.
One (but not causing the error message) is, that you try to add your profile instance to portfolio property of your portfolia instance. Portfolio has no property portfolio.
Regarding your errormessage, try following:
def portfolio = new Portfolio(portfolioName:"Portfolio 1", ...)
portfolio.profile = new Profile(...)
portfolio.save(failOnError: true)
For further reading, look at the Many-to-one and one-to-one (GORM) section of the grails docs.
I use grails-1.3.2 and hbase plugin.
I have some difficulty in creating one-to-Many association with
hbase (i can work with hibernate), so
i decided to try create one-to-Many association with using ArrayList.
Here are my domain classes and controllers:
class Contacts {
String con
static constraints = {}
}
class ContactsController {
def create = {
def contact = new Contacts()
contact.con = params.con
contact.save(flush:true)
}
}
class User {
String firstname
String lastname
// static hasMany = [contact: Contacts]
static ArrayList<Contacts> contact
static constraints = {}
}
class UserController{
def create = {
def user = new User()
user.properties = params
user.save(flush: true)
}
def addContact = {
def user = User.get(params.userID)
def contact = Contacts.get(params.contactID)
user.contact.add(contact)
user.save(flush:true)
}
}
In addContact action user.contact = null, so it can not work.
In user does nor appear contact field.
Can someone help me understand what i have to do for saving ArrayList in db?
I don't know anything about hbase, but the static contact property of the User class looks very suspicious. The fact that this property is static, implies that every user has the same contact list, which seems unlikely to be the desired behaviour.
In a standard GORM domain model - assuming you want each User to have their own contact list - this would be defined
class User {
String firstname
String lastname
static hasMany = [contact: Contacts]
}
Although it looks like we're also defining a static property here, it's actually just the definition of how the Contact and User classes are related (AKA mapping) that is static. The contact property that is dynamically added to the User class is non-static.
Aside
I recommend renaming the Contacts class to Contact and the contact property to contacts. The GORM mapping would then look like this:
class User {
String firstname
String lastname
static hasMany = [contacts: Contact]
}