2017-04-14 99 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對您有用的回覆 –

相關問題