gson.toJson()在Servlet中抛出StackOverflowError [英] gson.toJson() throws StackOverflowError in Servlet
问题描述
我有客户对象列表
List<Client> clientsList=new ArrayList<Client>();
clientsList=clientDao.GetAllClients();
实体客户有其他列表作为属性:
Entity Client has others list as attributes:
@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格式时
and when i try to convert list of clients to json format
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)
推荐答案
那是因为您的实体具有双向连接。因此,例如客户
有一组租
s,每个租金都有对客户的引用
。当您尝试序列化客户端
时,您序列化其租金
然后您必须序列化每个客户端
in Rent
等等。这就是导致 StackOverflowError
的原因。
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
.
要解决此问题,您必须将某些属性标记为 transient
(或使用一些类似的anotation),例如在 Rent $ c $中使用
transient Client
c>然后任何编组的lib都会忽略这个属性。
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.
如果是Gson,你可以用另一种方式来标记那些做的字段希望通过 @Expose
包含在json中并使用以下命令创建gson对象:
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。另外,我想提一下将JPA实体转换为json并将其发送到某个地方通常不是一个好主意。我建议创建一个DTO(数据传输对象)类,其中只包含您需要的信息,理想情况下只使用简单类型,如 int
,日期
, String
等等。如果您对此方法有疑问,可以谷歌 DTO
,数据传输对象
或点击此链接: https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm
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()在Servlet中抛出StackOverflowError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!