简体   繁体   English

尝试将域类序列化为 JSON 时出现 Grails 堆栈溢出错误

[英]Grails stack overflow error when trying to serialize domain class to JSON

More beginner problems for me with Groovy/Grails.更多关于 Groovy/Grails 的初学者问题。

Groovy version 2.4.8 Grails version 2.5.1 Groovy 版本 2.4.8 Grails 版本 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.我尝试了多种方法来序列化我的域类之一的实例或该域类的实例的 ArrayList。

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.我尝试从用户表中进行简单的获取,但收到一条错误消息,指出没有 id 字段。 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用户表的ddl

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. User 是 Postresql 中的一个关键字,所以我只是重构为 EndUser。

I suspect there is some issue with the data structure you have, which is causing the JSON builder to go into an infinite loop.我怀疑您拥有的数据结构存在一些问题,这导致 JSON 构建器进入无限循环。

You may want to review this for info on issues with dates: https://issues.apache.org/jira/browse/GROOVY-7682您可能需要查看有关日期问题的信息: https : //issues.apache.org/jira/browse/GROOVY-7682

This may work instead:这可能会起作用:

import grails.converters.JSON
def json = new JSON(a1)

I can't find this documented anywhere, but don't use JsonOutput for domain objects.我在任何地方都找不到这个文档,但不要将 JsonOutput 用于域对象。

I just ran into a similar issue.我刚刚遇到了类似的问题。 DomainObject instances have this "neat" property called all which will return every instance of the domain object. DomainObject 实例有这个名为all “整洁”属性,它将返回域对象的每个实例。

When JsonOutput tries to serialize your object, it uses DefaultGroovyMethods.getProperties, which includes the all property.当 JsonOutput 尝试序列化您的对象时,它使用 DefaultGroovyMethods.getProperties,其中包括all属性。 This means that your code will cause hibernate to load EVERY copy of your Advisor class into memory.这意味着您的代码将导致 hibernate 将您的 Advisor 类的每个副本加载到内存中。

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.在您的情况下,当您的 a1 类被呈现时,它包括“all”属性,这是所有顾问的完整列表。 Each Advisor also has an "all" property so it tries to render every advisor.每个顾问还有一个“all”属性,因此它会尝试呈现每个顾问。 And so on.等等。 Eventually giving you your stack overflow.最终给你你的堆栈溢出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM