2017-04-14 100 views
0

我有对象的客户gson.toJson()中抛出StackOverflowError在Servlet的

List<Client> clientsList=new ArrayList<Client>(); 
clientsList=clientDao.GetAllClients(); 

实体客户端具有其他列表作为属性列表:

@ManyToOne(optional=false) 
private User createdBy; 


@ManyToMany(mappedBy = "Clients") 
private Set<ClientType> Types=new HashSet(); 


@ManyToOne(optional=false) 
private LeadSource id_LeadSource; 
@ManyToOne(optional=false) 
private Agencie id_Agencie; 

@OneToMany(cascade=CascadeType.ALL,mappedBy="Owner") 
private Set<Propertie> properties=new HashSet(); 

@OneToMany(cascade=CascadeType.ALL,mappedBy="buyer") 
private Set<Sale> sales=new HashSet(); 

@OneToMany(cascade=CascadeType.ALL,mappedBy = "client") 
private Set<Rent> Rents=new HashSet(); 

@OneToMany(cascade=CascadeType.ALL,mappedBy = "clientDoc") 
private Set<Document> Docuements=new HashSet(); 

,当我尝试转换的客户端列表JSON格式

out.write(new Gson().toJson(clientsList)); 

我得到这个错误:

java.lang.StackOverflowError 
at com.google.gson.stream.JsonWriter.beforeName(JsonWriter.java:603) 
at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:401) 
at com.google.gson.stream.JsonWriter.value(JsonWriter.java:512) 
at com.google.gson.internal.bind.TypeAdapters$8.write(TypeAdapters.java:270) 
at com.google.gson.internal.bind.TypeAdapters$8.write(TypeAdapters.java:255) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:113) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:240) 

回答

5

这是因为您的实体具有双向连接。因此,例如Client有一组Rent s和每个租金有一个参考Client。当你尝试序列化一个Client你序列化其Rents,然后你必须序列化每个ClientRent等。这是导致StackOverflowError的原因。

为了解决这个问题,你将有一些性能transient标记(或使用一些类似anotation),例如使用transient ClientRent那么任何编组的lib会忽略这个属性。

在GSON的情况下,你可以做其他方式标记这些领域你要包含在JSON与@Expose和创建的GSON对象:

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); 

附:另外,我想提一下,将JPA实体转换为json并将其发送到某处通常不是一个好主意。我建议创建一个DTO(数据传输对象)类,其中只包含您需要的信息,理想情况下仅使用简单类型,如int,DateString等。如果您对此方法有疑问,您可以谷歌搜索DTO,Data Transfer Object或点击以下链接:https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm

+0

非常感谢@Nestor Sokil对您有用的回复 –

相关问题