gorm-hibernate5 icon indicating copy to clipboard operation
gorm-hibernate5 copied to clipboard

How to convert entity to JSON string when using gorm-hibernate in SpringBoot

Open wureka opened this issue 5 years ago • 5 comments

I use gorm-hibernate in SpringBoot (and Micronaut) with Groovy. When I use JsonSlurper/JsonBuilder to convert entity class to JSON string, it happens to Stackoverflow error . You may refer to below link for getting detail exception dump: https://stackoverflow.com/questions/56122167/when-using-hibernate-gorm-how-to-convert-domain-class-into-json-string

It seems that both JsonSlurper and JsonBuilder can not handle entity classes built from GORM.

So, is there any elegant way to convert domain classes to JSON string in Micronaut ? Please don't ask me to use Jackson library because the approach way of Jackson is so urgly.

I know in Grails, grails.converters.JSON can convert a domain class to JSON string without any problem. So, is it possible to add the similar feature of grails.converters.JSON into gorm-hibernate ?

wureka avatar May 14 '19 02:05 wureka

What is you dislike about Jackson?

graemerocher avatar May 14 '19 05:05 graemerocher

What is you dislike about Jackson?

@graemerocher Don't you think that Jackson's usage is too verbose? If you tried Groovy's way (Jsonslurper/JsonBuilder) or Grails's grails.converters.JSON, you should realize that either Groovy or Grails approach to JSON is so elegant and neat!

wureka avatar May 14 '19 11:05 wureka

Depends on the use case, sometimes it is simpler if the customization is simple. For example to change the name of a single property it is just @JsonProperty

graemerocher avatar May 14 '19 12:05 graemerocher

gorm adds a method called getAll() to domain objects which will fetch every instance. Because there is a no argument version of this method, it also shows up as the property all.

When JsonBuilder/JsonOutput tries to convert an object to JSON, it uses DefaultGroovyMethods.getProperties, which fetches the property "all", which then causes hibernate to fetch every instance of your domain object.

If you have a lot of those domain instances, you run out of memory. If you can store all of your instances into ram, then you get that stackoverflow error as every domainInstance tries to render all, which renders a list of domain instances where each one tries to render all.

Anyway, not sure what you can do about it, but that's where your stackoverflow is coming from.

tircnf avatar Mar 15 '20 06:03 tircnf

Same problem here. Thank you so much for analyzing this.

It is possible exclude attributes from being serialized to JSON. But this doesn't seem to be enough:

def generator = new JsonGenerator.Options().excludeFieldsByName('all', 'getAll').build()
println generator.toJson(myGormEntity)   // <=== still kaboooomm :-(

Doogiemuc avatar Sep 13 '20 18:09 Doogiemuc