gson.toJson() throws StackOverflowError
That problem is that you have a circular reference.
In the BomModule
class you are referencing to:
private Collection<BomModule> parentModules;
private Collection<BomModule> subModules;
That self reference to BomModule
, obviously, not liked by GSON at all.
A workaround is just set the modules to null
to avoid the recursive looping. This way I can avoid the StackOverFlow-Exception.
item.setModules(null);
Or mark the fields you don't want to show up in the serialized json by using the transient
keyword, eg:
private transient Collection<BomModule> parentModules;
private transient Collection<BomModule> subModules;
gson.toJson() throws StackOverflowError in Servlet
That is because your entities have bidirectional connections. So for example Client
has a set of Rent
s and each rent has a reference to Client
. When you try serializing a Client
you serialize its Rents
and then you have to serialize each Client
in Rent
and so on. This is what causes the StackOverflowError
.
To solve this problem you will have to mark some properties as transient
(or use some similar anotation), for example use transient Client
in Rent
Then any marshalling lib will just ignore this property.
In case of Gson you can do the other way around marking those field you do want to be included in json with @Expose
and creating the gson object with:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
P.S. Also, I would like to mention that converting your JPA entity to json and sending it somewhere is generally not a very good idea. I'd recommend creating a DTO(Data Transfer Object) class where you include only the info you need and ideally using only simple types like int
, Date
, String
and so on. If you have questions about this approach you can google for DTO
, Data Transfer Object
or follow this link: https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm
GSON.toJson(new RuntimeException()) throws StackOverflowError
Upgrading to version Gson 2.6.1 solved the problem
Gson.fromJson() throws StackOverflowError
I can't reproduce this problem. One of two things are wrong here:
- Your beans are not defined as you say they are. Check to see if they have other fields hidden within the getter and setter method section. This can happen if you have a circular reference.
- You've stated in the comments that this is likely to be your problem. I recommend:
- Remove the extra fields from your bean
- Create a new class that contains the extra fields, and a field for the
Asking
instance - Deserialize the
Asking
instance using Gson, and then pass it into the new class's constructor.
- You've stated in the comments that this is likely to be your problem. I recommend:
You are doing something unexpected with your setup of the
gson.fromJson
method. Here's what I'm using that works great:public static void parseJSON(String jsonString) {
Gson gsonParser = new Gson();
Type collectionType = new TypeToken<Asking>(){}.getType();
Asking gsonResponse = gsonParser.fromJson(jsonString, collectionType);
System.out.println(gsonResponse);
}
Either check your bean class definitions for extra fields, or, failing that, try to make your deserialization match mine.
java.lang.StackOverflowError for gson get methods
first change If you need to close a stream, then best practice would be to use the try-with-resources statement link
try (EntityManager em = emf.createEntityManager()) {
Query q = em.createQuery("select p from Pet p where p.death is null");
return (List<Pet>) q.getResultList();
}
version 1 send only dto send only the field you need
@GET
@Path("/living")
@Produces(MediaType.APPLICATION_JSON)
public Response getLivingPets(){
return Response.ok().entity(gson.toJson(pf.getLivingPets().stream().map(Dto::new).collect(Collectors.toList()))).build();
}
//adn created class your DTO
public class Dto {
private final Integer id;
private final String name;
public Dto(Pet pet) {
this.id= pet.getId();
this.name= pet.getName();
}
}
version 2 create TypeAdapter where is the feedback reference to Pet
@GET
@Path("/living")
@Produces(MediaType.APPLICATION_JSON)
public Response getLivingPets(){
Gson gson = new GsonBuilder().registerTypeAdapter(Owner.class, new PetAdapter()).create();
return Response.ok().entity(gson.toJson(pf.getLivingPets())).build();
}
created PetAdapter
public class PetAdapter extends TypeAdapter<Owner> {
@Override
public void write(JsonWriter out, Owner value) throws IOException {
out.beginObject();
out.name("id");
out.value(value.getId());
out.endObject();
//NOT USE PET
}
@Override
public Owner read(JsonReader in) throws IOException {
return null;
}
}
Related Topics
Auto Adjust the Height of Rows in a Jtable
Service Layer and Controller: Who Takes Care of What
Can a Private Method in Super Class Be Overridden in the Sub-Class
How to Convert an Integer to Localized Month Name in Java
Calling Getters on an Object VS. Storing It as a Local Variable (Memory Footprint, Performance)
Formatting a String to a Currency Format in Jasper Report
Java: How to Test on Array Equality
Totally Confused with Java.Exe
Junit - Run Set Up Method Once
Xml Element with Attribute and Content Using Jaxb
What Are the Rules Dictating the Inheritance of Static Variables in Java
Java - How to Create New Entry (Key, Value)