Reputation: 91
More beginner problems for me with Groovy/Grails.
Groovy version 2.4.8 Grails version 2.5.1
I have tried multiple ways to serialize an instance of one of my domain classes or an ArrayList of instances of that domain class.
When trying to serialize a single instance I get a stack overflow error.
The code and stack trace is shown below
def getAdvisors(String keystrokes, String firm) {
def advisors = priceBlotterService.advisorsForKeystrokes(keystrokes, "", 30)
def a1 = advisors[0]
def json = JsonOutput.toJson(a1)
}
Caused by InvocationTargetException: null
->> 198 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . in java.lang.Thread
Caused by StackOverflowError: null
->> 100 | invoke in org.codehaus.groovy.reflection.CachedMethod
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 62 | getProperty in groovy.lang.MetaBeanProperty
| 42 | getValue in groovy.lang.PropertyValue
| 388 | getProperties in org.codehaus.groovy.runtime.DefaultGroovyMethods
| 290 | writeObject in groovy.json.JsonOutput
| 329 | writeArray in ''
| 286 | writeObject in ''
| 424 | writeMap in ''
| 294 | writeObject in ''
| 329 | writeArray in ''
| 286 | writeObject in ''
| 424 | writeMap in ''
Advisor, Case, and Firm Classes:
class Advisor {
String firstName
String lastName
String fullName
String city
String state
Firm firm
static belongsTo = [Case, Firm]
static hasMany = [cases:Case]
static constraints = {
}
}
class Case {
String caseCode
String internalComment
String externalComment
Date dateCreated
String createdBy
Date dateUpdated
String updatedBy
static belongsTo = [owner:User, caseStatusType:CaseStatusType]
static hasMany = [advisor:Advisor]
static mapping = {
dateCreated sqlType: "date"
dateUpdated sqlType: "date"
}
static constraints = {
dateCreated(nullabe: false)
dateUpdated(nullable: false)
}
}
class Firm {
String name
static constraints = {
}
}
Edit:
I found a fundamental problem with my domain class/table that could have something to do with this and needs to be resolved.
I try to do a simple get from the user table and I get an error message indicating there is no id field. Having a hard time figuring out what is going on. Some details are below.
line of code
User[] users = User.findAll()
error message
org.springframework.jdbc.BadSqlGrammarException: Hibernate operation: could not extract ResultSet; bad SQL grammar [n/a]; nested exception is org.postgresql.util.PSQLException: ERROR: column this_.id does not exist Position: 8
User class
class User {
String firstName
String lastName
static constraints = {
}
}
ddl for user table
CREATE TABLE "user"
(
id BIGINT DEFAULT nextval('user_id_seq'::regclass) PRIMARY KEY NOT NULL,
first_name VARCHAR(30),
last_name VARCHAR(30),
version BIGINT
);
CREATE UNIQUE INDEX user_id_uindex ON "user" (id);
Edit:
Fixed issuer with User table/class. User is a keyword in Postresql so I just refactored to EndUser.
Upvotes: 0
Views: 1747
Reputation: 1121
I can't find this documented anywhere, but don't use JsonOutput for domain objects.
I just ran into a similar issue. DomainObject instances have this "neat" property called all
which will return every instance of the domain object.
When JsonOutput tries to serialize your object, it uses DefaultGroovyMethods.getProperties, which includes the all
property. This means that your code will cause hibernate to load EVERY copy of your Advisor class into memory.
In my case I ran out of memory. My system got stuck in garbage collection loops.
In your case, when your a1 class is being rendered, it is including the 'all' property, which is the full list of all Advisors. Each Advisor also has an "all" property so it tries to render every advisor. And so on. Eventually giving you your stack overflow.
Upvotes: 0
Reputation: 765
I suspect there is some issue with the data structure you have, which is causing the JSON builder to go into an infinite loop.
You may want to review this for info on issues with dates: https://issues.apache.org/jira/browse/GROOVY-7682
This may work instead:
import grails.converters.JSON
def json = new JSON(a1)
Upvotes: 1