Gson.Tojson() Throws Stackoverflowerror

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 Rents 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:

  1. 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:

      1. Remove the extra fields from your bean
      2. Create a new class that contains the extra fields, and a field for the Asking instance
      3. Deserialize the Asking instance using Gson, and then pass it into the new class's constructor.
  2. 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



Leave a reply



Submit