JSONObject().put 使用 List 递归地抛出 DefinedObjectException
JSONObject().put using a List Throws recursivelyDefinedObjectException
我有一个查询生成 List
of Tickets
像这样使用休眠 :
Query query = session.createQuery(
"SELECT T.id, T.Objet, T.Details, T.Etat,T.Severity, T.createDateTime, T.user, T.Attachment, U.lastName, L.nomLogiciel, V.nomVersion,T.AssignedTo,T.ClosedBy,T.closedDateTime,T.assignedDateTime, U.firstName, U.username, U.Email, U.Phone FROM Ticket T, User U, Logiciel L, Version V "
+ "WHERE T.user= :user and T.user=U.user_id AND L.logiciel_id=T.Logiciel AND T.Version=V.version_id AND T.Etat!='fermer' ORDER BY T.createDateTime ")
.setParameter("user", user);
我试图 put JSONObject 中的列表:
List allTickets = ticketDao.getTicketsByUserDao(user);
JSONObject jo = new JSONObject();
jo.put("ticket", allTickets);
它抛出这个异常:
Hibernate: select ticket0_.ticket_id as col_0_0_, ticket0_.objet as col_1_0_, ticket0_.details as col_2_0_, ticket0_.etat as col_3_0_, ticket0_.severity as col_4_0_, ticket0_.createDateTime as col_5_0_, ticket0_.user_id as col_6_0_, ticket0_.attachment_path as col_7_0_, user1_.last_name as col_8_0_, logiciel2_.nom_logiciel as col_9_0_, version3_.nom_version as col_10_0_, ticket0_.assigned_to as col_11_0_, ticket0_.closed_by as col_12_0_, ticket0_.closedDateTime as col_13_0_, ticket0_.assignedDateTime as col_14_0_, user1_.first_name as col_15_0_, user1_.username as col_16_0_, user1_.email as col_17_0_, user1_.phone as col_18_0_, user4_.user_id as user_id1_9_, user4_.email as email2_9_, user4_.etat as etat3_9_, user4_.phone as phone4_9_, user4_.currentAccessDate as currenta5_9_, user4_.dateExpiration as dateexpi6_9_, user4_.first_name as first_na7_9_, user4_.lastAccessDate as lastacce8_9_, user4_.last_name as last_nam9_9_, user4_.password as passwor10_9_, user4_.structure_id as structu12_9_, user4_.username as usernam11_9_ from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' order by ticket0_.createDateTime
Hibernate: select tickets0_.user_id as user_id14_8_2_, tickets0_.ticket_id as ticket_i1_8_2_, tickets0_.ticket_id as ticket_i1_8_1_, tickets0_.assigned_to as assigned2_8_1_, tickets0_.attachment_path as attachme3_8_1_, tickets0_.closed_by as closed_b4_8_1_, tickets0_.details as details5_8_1_, tickets0_.etat as etat6_8_1_, tickets0_.logiciel_id as logiciel7_8_1_, tickets0_.objet as objet8_8_1_, tickets0_.severity as severity9_8_1_, tickets0_.version_id as version10_8_1_, tickets0_.assignedDateTime as assigne11_8_1_, tickets0_.closedDateTime as closedd12_8_1_, tickets0_.createDateTime as created13_8_1_, tickets0_.user_id as user_id14_8_1_, planificat1_.planif_id as planif_i1_4_0_, planificat1_.observation as observat2_4_0_, planificat1_.date_debut_planif as date_deb3_4_0_, planificat1_.date_debut_realise as date_deb4_4_0_, planificat1_.date_fin_planif as date_fin5_4_0_, planificat1_.date_fin_realise as date_fin6_4_0_, planificat1_.ticket_id as ticket_i7_4_0_ from tickets tickets0_ left outer join planification planificat1_ on tickets0_.ticket_id=planificat1_.ticket_id where tickets0_.user_id in (select user4_.user_id from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' )
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select responses0_.user_id as user_id5_5_4_, responses0_.response_id as response1_5_4_, responses0_.response_id as response1_5_3_, responses0_.response as response2_5_3_, responses0_.createDateTime as createda3_5_3_, responses0_.ticket_id as ticket_i4_5_3_, responses0_.user_id as user_id5_5_3_, ticket1_.ticket_id as ticket_i1_8_0_, ticket1_.assigned_to as assigned2_8_0_, ticket1_.attachment_path as attachme3_8_0_, ticket1_.closed_by as closed_b4_8_0_, ticket1_.details as details5_8_0_, ticket1_.etat as etat6_8_0_, ticket1_.logiciel_id as logiciel7_8_0_, ticket1_.objet as objet8_8_0_, ticket1_.severity as severity9_8_0_, ticket1_.version_id as version10_8_0_, ticket1_.assignedDateTime as assigne11_8_0_, ticket1_.closedDateTime as closedd12_8_0_, ticket1_.createDateTime as created13_8_0_, ticket1_.user_id as user_id14_8_0_, user2_.user_id as user_id1_9_1_, user2_.email as email2_9_1_, user2_.etat as etat3_9_1_, user2_.phone as phone4_9_1_, user2_.currentAccessDate as currenta5_9_1_, user2_.dateExpiration as dateexpi6_9_1_, user2_.first_name as first_na7_9_1_, user2_.lastAccessDate as lastacce8_9_1_, user2_.last_name as last_nam9_9_1_, user2_.password as passwor10_9_1_, user2_.structure_id as structu12_9_1_, user2_.username as usernam11_9_1_, planificat3_.planif_id as planif_i1_4_2_, planificat3_.observation as observat2_4_2_, planificat3_.date_debut_planif as date_deb3_4_2_, planificat3_.date_debut_realise as date_deb4_4_2_, planificat3_.date_fin_planif as date_fin5_4_2_, planificat3_.date_fin_realise as date_fin6_4_2_, planificat3_.ticket_id as ticket_i7_4_2_ from responses responses0_ inner join tickets ticket1_ on responses0_.ticket_id=ticket1_.ticket_id left outer join users user2_ on ticket1_.user_id=user2_.user_id left outer join planification planificat3_ on ticket1_.ticket_id=planificat3_.ticket_id where responses0_.user_id in (select user4_.user_id from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' )
org.json.JSONException: JavaBean object contains recursively defined member variable of key "planification"
at org.json.JSONObject.recursivelyDefinedObjectException(JSONObject.java:2722)
at org.json.JSONObject.populateMap(JSONObject.java:1558)
at org.json.JSONObject.<init>(JSONObject.java:372)
at org.json.JSONObject.wrap(JSONObject.java:2496)
at org.json.JSONObject.populateMap(JSONObject.java:1563)
at org.json.JSONObject.<init>(JSONObject.java:372)
at org.json.JSONObject.wrap(JSONObject.java:2496)
at org.json.JSONObject.populateMap(JSONObject.java:1563)
at org.json.JSONObject.populateMap(JSONObject.java:1530)
at org.json.JSONObject.<init>(JSONObject.java:367)
at org.json.JSONObject.wrap(JSONObject.java:2499)
at org.json.JSONObject.wrap(JSONObject.java:2457)
at org.json.JSONArray.addAll(JSONArray.java:1609)
at org.json.JSONArray.<init>(JSONArray.java:176)
at org.json.JSONObject.wrap(JSONObject.java:2478)
at org.json.JSONObject.populateMap(JSONObject.java:1563)
at org.json.JSONObject.populateMap(JSONObject.java:1530)
at org.json.JSONObject.<init>(JSONObject.java:367)
at org.json.JSONObject.wrap(JSONObject.java:2499)
at org.json.JSONObject.wrap(JSONObject.java:2457)
at org.json.JSONArray.addAll(JSONArray.java:1661)
at org.json.JSONArray.<init>(JSONArray.java:228)
at org.json.JSONObject.wrap(JSONObject.java:2481)
at org.json.JSONObject.wrap(JSONObject.java:2457)
at org.json.JSONArray.addAll(JSONArray.java:1609)
at org.json.JSONArray.<init>(JSONArray.java:176)
at org.json.JSONObject.put(JSONObject.java:1771)
at com.myproject.helpdesk.controllers.TicketManagement.getTicketsByUser(TicketManagement.java:610)
at com.myproject.helpdesk.controllers.TicketManagement.doGet(TicketManagement.java:95)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.myproject.helpdesk.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:33)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:196)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:366)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:639)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:847)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1680)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
什么是 recursivelyDefinedObjectException
?我的 Google 搜索总是指向递归和函数的主题,没有例外。
调试时,allTickets
列表包含 4 个对象,如下所示:
[
[Ljava.lang.Object;@10e63606,
[Ljava.lang.Object;@3c76d000,
[Ljava.lang.Object;@5f5bfd07,
[Ljava.lang.Object;@3a14ab96
]
他是第一个对象的内容,例如:
[1455, test ticket, hello world, créé, Critique, 2022-02-03T15:48:41.058086, com.myproject.helpdesk.models.User@6f643c88, null, CTH, dummy, 10.1.1.v, null, null, 2022-02-03T15:48:41.058086, 2022-02-03T15:48:41.058086, CTH, CTH, email@something.com, 00999999999]
环境:
- Eclipse:版本:2021-06 (4.20.0) 构建 ID:20210612-2011
- Java 8
- 我的JSONOject来自这个dependency
感谢任何帮助。
编辑:添加实体
获取 Tickets
列表是导致问题的原因。
门票
@Entity
@Table(name = "tickets")
public class Ticket implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ticket_id")
private int ticket_id;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false, insertable = true)
private User user;
@OneToMany(fetch = FetchType.EAGER,mappedBy="ticket")
private List<Response> response;
@OneToOne(mappedBy = "ticket")
private Planification planification;
规划
@Entity
@Table(name = "planification")
public class Planification implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "planif_id")
private int planifId;
@OneToOne
@JoinColumn(name = "ticket_id",unique = true)
private Ticket ticket;
用户
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
private int user_id;
@OneToMany(fetch = FetchType.EAGER ,mappedBy="user")
@Fetch(value = FetchMode.SUBSELECT)
private List<Ticket> tickets;
@OneToMany(fetch = FetchType.EAGER ,mappedBy="user")
@Fetch(value = FetchMode.SUBSELECT)
private List<Response> responses;
@ManyToOne(fetch = FetchType.EAGER ,cascade = CascadeType.ALL)
@JoinColumn(name = "structure_id")
private Structure structure;
回应
@Entity
@Table(name = "responses")
public class Response implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "response_id")
private int responseId;
@ManyToOne
@JoinColumn(name = "ticket_id", nullable = false, insertable = true)
private Ticket ticket;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false, insertable = true)
private User user;
结构
@Entity
@Table(name = "structure")
public class Structure implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "structure_id")
private int structure_id;
@OneToMany(mappedBy = "structure")
private List<User> user;
编辑 2:
调试时我注意到 User
的 Ticket
的 Structure
有异常堆栈跟踪作为其 PersistentBag 的内容,
到底是什么原因造成的?!我检查了我的实体定义,它们对我来说没问题。
旁注
我的Ticket
对象包含User
对象,它包含User
s的Ticket
s的列表,一直循环下去,无限递归,这正常吗?我的实体定义错了吗?我该如何解决这个问题?
你可以用地图。
Map<String,Object> mapObject = new HashMap<>();
List allTickets = ticketDao.getTicketsByUserDao(user);
mapObject.put("ticket",allTickets);
错误:
allTickets
列表包含一个无限递归的 User
对象,因此无法解析为 JSONObject
。
是什么原因造成的?
此查询:
Query query = session.createQuery(
"SELECT T.id, T.Objet, T.Details, T.Etat,T.Severity, T.createDateTime, T.user, T.Attachment, U.lastName, L.nomLogiciel, V.nomVersion,T.AssignedTo,T.ClosedBy,T.closedDateTime,T.assignedDateTime, U.firstName, U.username, U.Email, U.Phone FROM Ticket T, User U, Logiciel L, Version V "
+ "WHERE T.user= :user and T.user=U.user_id AND L.logiciel_id=T.Logiciel AND T.Version=V.version_id AND T.Etat!='fermer' ORDER BY T.createDateTime ")
.setParameter("user", user);
这里强调T.user
:
Tickets
table 中没有名为 User
的列,取而代之的是 user_id
,因此 query.list()
方法返回了一个无限实例递归 User
对象而不是 user_id
,它是一个 integer
,* 我认为 *.
修复
将 T.user
更改为 T.user_id
。
现在可以将列表解析为 JSONObject
,没有任何错误。
我看到你设法修复了它,但为了完整性我会添加另一个选项。我设法用两个简单的 类 重新创建了你的确切异常,它们的实例形成了一个循环引用,就像你的情况一样。
用户:
public class User {
private long id;
private Ticket ticket;
public User(long id) {
this.id = id;
}
//getters and setters
}
门票
public class Ticket {
private long id;
private User user;
public Ticket(long id) {
this.id = id;
}
//getters and setters
}
设置:
User user = new User(1);
Ticket ticket = new Ticket(2);
user.setTicket(ticket);
ticket.setUser(user);
List<User> users = Arrays.asList(user, user, user);
实例相互引用到无穷大,就像你的情况一样。这在 java 中完全有效,但在 json 中很难表示。根据我直接添加集合的测试,导致 Exception in thread "main" org.json.JSONException: JavaBean object contains recursively defined member variable of key "ticket"
.
JSONObject jsonObject = new JSONObject();
jsonObject.put("users", users);
System.out.println(jsonObject);
jsonObject.put(key, collection)
从集合创建 json 数组,但由于某些原因无法处理集合元素中的循环引用。
修复它的解决方法 是手动创建 JSONArray
,然后迭代集合,手动添加每个元素 JSONArray。然后在JSONObject
.
中添加准备好的json数组
JSONArray jsonArray = new JSONArray();
users.forEach(jsonArray::put);
JSONObject jsonObject = new JSONObject();
jsonObject.put("users", jsonArray);
System.out.println(jsonObject);
我有一个查询生成 List
of Tickets
像这样使用休眠 :
Query query = session.createQuery(
"SELECT T.id, T.Objet, T.Details, T.Etat,T.Severity, T.createDateTime, T.user, T.Attachment, U.lastName, L.nomLogiciel, V.nomVersion,T.AssignedTo,T.ClosedBy,T.closedDateTime,T.assignedDateTime, U.firstName, U.username, U.Email, U.Phone FROM Ticket T, User U, Logiciel L, Version V "
+ "WHERE T.user= :user and T.user=U.user_id AND L.logiciel_id=T.Logiciel AND T.Version=V.version_id AND T.Etat!='fermer' ORDER BY T.createDateTime ")
.setParameter("user", user);
我试图 put JSONObject 中的列表:
List allTickets = ticketDao.getTicketsByUserDao(user);
JSONObject jo = new JSONObject();
jo.put("ticket", allTickets);
它抛出这个异常:
Hibernate: select ticket0_.ticket_id as col_0_0_, ticket0_.objet as col_1_0_, ticket0_.details as col_2_0_, ticket0_.etat as col_3_0_, ticket0_.severity as col_4_0_, ticket0_.createDateTime as col_5_0_, ticket0_.user_id as col_6_0_, ticket0_.attachment_path as col_7_0_, user1_.last_name as col_8_0_, logiciel2_.nom_logiciel as col_9_0_, version3_.nom_version as col_10_0_, ticket0_.assigned_to as col_11_0_, ticket0_.closed_by as col_12_0_, ticket0_.closedDateTime as col_13_0_, ticket0_.assignedDateTime as col_14_0_, user1_.first_name as col_15_0_, user1_.username as col_16_0_, user1_.email as col_17_0_, user1_.phone as col_18_0_, user4_.user_id as user_id1_9_, user4_.email as email2_9_, user4_.etat as etat3_9_, user4_.phone as phone4_9_, user4_.currentAccessDate as currenta5_9_, user4_.dateExpiration as dateexpi6_9_, user4_.first_name as first_na7_9_, user4_.lastAccessDate as lastacce8_9_, user4_.last_name as last_nam9_9_, user4_.password as passwor10_9_, user4_.structure_id as structu12_9_, user4_.username as usernam11_9_ from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' order by ticket0_.createDateTime
Hibernate: select tickets0_.user_id as user_id14_8_2_, tickets0_.ticket_id as ticket_i1_8_2_, tickets0_.ticket_id as ticket_i1_8_1_, tickets0_.assigned_to as assigned2_8_1_, tickets0_.attachment_path as attachme3_8_1_, tickets0_.closed_by as closed_b4_8_1_, tickets0_.details as details5_8_1_, tickets0_.etat as etat6_8_1_, tickets0_.logiciel_id as logiciel7_8_1_, tickets0_.objet as objet8_8_1_, tickets0_.severity as severity9_8_1_, tickets0_.version_id as version10_8_1_, tickets0_.assignedDateTime as assigne11_8_1_, tickets0_.closedDateTime as closedd12_8_1_, tickets0_.createDateTime as created13_8_1_, tickets0_.user_id as user_id14_8_1_, planificat1_.planif_id as planif_i1_4_0_, planificat1_.observation as observat2_4_0_, planificat1_.date_debut_planif as date_deb3_4_0_, planificat1_.date_debut_realise as date_deb4_4_0_, planificat1_.date_fin_planif as date_fin5_4_0_, planificat1_.date_fin_realise as date_fin6_4_0_, planificat1_.ticket_id as ticket_i7_4_0_ from tickets tickets0_ left outer join planification planificat1_ on tickets0_.ticket_id=planificat1_.ticket_id where tickets0_.user_id in (select user4_.user_id from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' )
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select responses0_.user_id as user_id5_5_4_, responses0_.response_id as response1_5_4_, responses0_.response_id as response1_5_3_, responses0_.response as response2_5_3_, responses0_.createDateTime as createda3_5_3_, responses0_.ticket_id as ticket_i4_5_3_, responses0_.user_id as user_id5_5_3_, ticket1_.ticket_id as ticket_i1_8_0_, ticket1_.assigned_to as assigned2_8_0_, ticket1_.attachment_path as attachme3_8_0_, ticket1_.closed_by as closed_b4_8_0_, ticket1_.details as details5_8_0_, ticket1_.etat as etat6_8_0_, ticket1_.logiciel_id as logiciel7_8_0_, ticket1_.objet as objet8_8_0_, ticket1_.severity as severity9_8_0_, ticket1_.version_id as version10_8_0_, ticket1_.assignedDateTime as assigne11_8_0_, ticket1_.closedDateTime as closedd12_8_0_, ticket1_.createDateTime as created13_8_0_, ticket1_.user_id as user_id14_8_0_, user2_.user_id as user_id1_9_1_, user2_.email as email2_9_1_, user2_.etat as etat3_9_1_, user2_.phone as phone4_9_1_, user2_.currentAccessDate as currenta5_9_1_, user2_.dateExpiration as dateexpi6_9_1_, user2_.first_name as first_na7_9_1_, user2_.lastAccessDate as lastacce8_9_1_, user2_.last_name as last_nam9_9_1_, user2_.password as passwor10_9_1_, user2_.structure_id as structu12_9_1_, user2_.username as usernam11_9_1_, planificat3_.planif_id as planif_i1_4_2_, planificat3_.observation as observat2_4_2_, planificat3_.date_debut_planif as date_deb3_4_2_, planificat3_.date_debut_realise as date_deb4_4_2_, planificat3_.date_fin_planif as date_fin5_4_2_, planificat3_.date_fin_realise as date_fin6_4_2_, planificat3_.ticket_id as ticket_i7_4_2_ from responses responses0_ inner join tickets ticket1_ on responses0_.ticket_id=ticket1_.ticket_id left outer join users user2_ on ticket1_.user_id=user2_.user_id left outer join planification planificat3_ on ticket1_.ticket_id=planificat3_.ticket_id where responses0_.user_id in (select user4_.user_id from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' )
org.json.JSONException: JavaBean object contains recursively defined member variable of key "planification"
at org.json.JSONObject.recursivelyDefinedObjectException(JSONObject.java:2722)
at org.json.JSONObject.populateMap(JSONObject.java:1558)
at org.json.JSONObject.<init>(JSONObject.java:372)
at org.json.JSONObject.wrap(JSONObject.java:2496)
at org.json.JSONObject.populateMap(JSONObject.java:1563)
at org.json.JSONObject.<init>(JSONObject.java:372)
at org.json.JSONObject.wrap(JSONObject.java:2496)
at org.json.JSONObject.populateMap(JSONObject.java:1563)
at org.json.JSONObject.populateMap(JSONObject.java:1530)
at org.json.JSONObject.<init>(JSONObject.java:367)
at org.json.JSONObject.wrap(JSONObject.java:2499)
at org.json.JSONObject.wrap(JSONObject.java:2457)
at org.json.JSONArray.addAll(JSONArray.java:1609)
at org.json.JSONArray.<init>(JSONArray.java:176)
at org.json.JSONObject.wrap(JSONObject.java:2478)
at org.json.JSONObject.populateMap(JSONObject.java:1563)
at org.json.JSONObject.populateMap(JSONObject.java:1530)
at org.json.JSONObject.<init>(JSONObject.java:367)
at org.json.JSONObject.wrap(JSONObject.java:2499)
at org.json.JSONObject.wrap(JSONObject.java:2457)
at org.json.JSONArray.addAll(JSONArray.java:1661)
at org.json.JSONArray.<init>(JSONArray.java:228)
at org.json.JSONObject.wrap(JSONObject.java:2481)
at org.json.JSONObject.wrap(JSONObject.java:2457)
at org.json.JSONArray.addAll(JSONArray.java:1609)
at org.json.JSONArray.<init>(JSONArray.java:176)
at org.json.JSONObject.put(JSONObject.java:1771)
at com.myproject.helpdesk.controllers.TicketManagement.getTicketsByUser(TicketManagement.java:610)
at com.myproject.helpdesk.controllers.TicketManagement.doGet(TicketManagement.java:95)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.myproject.helpdesk.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:33)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:196)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:366)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:639)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:847)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1680)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
什么是 recursivelyDefinedObjectException
?我的 Google 搜索总是指向递归和函数的主题,没有例外。
调试时,allTickets
列表包含 4 个对象,如下所示:
[
[Ljava.lang.Object;@10e63606,
[Ljava.lang.Object;@3c76d000,
[Ljava.lang.Object;@5f5bfd07,
[Ljava.lang.Object;@3a14ab96
]
他是第一个对象的内容,例如:
[1455, test ticket, hello world, créé, Critique, 2022-02-03T15:48:41.058086, com.myproject.helpdesk.models.User@6f643c88, null, CTH, dummy, 10.1.1.v, null, null, 2022-02-03T15:48:41.058086, 2022-02-03T15:48:41.058086, CTH, CTH, email@something.com, 00999999999]
环境:
- Eclipse:版本:2021-06 (4.20.0) 构建 ID:20210612-2011
- Java 8
- 我的JSONOject来自这个dependency
感谢任何帮助。
编辑:添加实体
获取 Tickets
列表是导致问题的原因。
门票
@Entity
@Table(name = "tickets")
public class Ticket implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ticket_id")
private int ticket_id;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false, insertable = true)
private User user;
@OneToMany(fetch = FetchType.EAGER,mappedBy="ticket")
private List<Response> response;
@OneToOne(mappedBy = "ticket")
private Planification planification;
规划
@Entity
@Table(name = "planification")
public class Planification implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "planif_id")
private int planifId;
@OneToOne
@JoinColumn(name = "ticket_id",unique = true)
private Ticket ticket;
用户
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
private int user_id;
@OneToMany(fetch = FetchType.EAGER ,mappedBy="user")
@Fetch(value = FetchMode.SUBSELECT)
private List<Ticket> tickets;
@OneToMany(fetch = FetchType.EAGER ,mappedBy="user")
@Fetch(value = FetchMode.SUBSELECT)
private List<Response> responses;
@ManyToOne(fetch = FetchType.EAGER ,cascade = CascadeType.ALL)
@JoinColumn(name = "structure_id")
private Structure structure;
回应
@Entity
@Table(name = "responses")
public class Response implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "response_id")
private int responseId;
@ManyToOne
@JoinColumn(name = "ticket_id", nullable = false, insertable = true)
private Ticket ticket;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false, insertable = true)
private User user;
结构
@Entity
@Table(name = "structure")
public class Structure implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "structure_id")
private int structure_id;
@OneToMany(mappedBy = "structure")
private List<User> user;
编辑 2:
调试时我注意到 User
的 Ticket
的 Structure
有异常堆栈跟踪作为其 PersistentBag 的内容,
到底是什么原因造成的?!我检查了我的实体定义,它们对我来说没问题。
旁注
我的Ticket
对象包含User
对象,它包含User
s的Ticket
s的列表,一直循环下去,无限递归,这正常吗?我的实体定义错了吗?我该如何解决这个问题?
你可以用地图。
Map<String,Object> mapObject = new HashMap<>();
List allTickets = ticketDao.getTicketsByUserDao(user);
mapObject.put("ticket",allTickets);
错误:
allTickets
列表包含一个无限递归的 User
对象,因此无法解析为 JSONObject
。
是什么原因造成的?
此查询:
Query query = session.createQuery(
"SELECT T.id, T.Objet, T.Details, T.Etat,T.Severity, T.createDateTime, T.user, T.Attachment, U.lastName, L.nomLogiciel, V.nomVersion,T.AssignedTo,T.ClosedBy,T.closedDateTime,T.assignedDateTime, U.firstName, U.username, U.Email, U.Phone FROM Ticket T, User U, Logiciel L, Version V "
+ "WHERE T.user= :user and T.user=U.user_id AND L.logiciel_id=T.Logiciel AND T.Version=V.version_id AND T.Etat!='fermer' ORDER BY T.createDateTime ")
.setParameter("user", user);
这里强调T.user
:
Tickets
table 中没有名为 User
的列,取而代之的是 user_id
,因此 query.list()
方法返回了一个无限实例递归 User
对象而不是 user_id
,它是一个 integer
,* 我认为 *.
修复
将 T.user
更改为 T.user_id
。
现在可以将列表解析为 JSONObject
,没有任何错误。
我看到你设法修复了它,但为了完整性我会添加另一个选项。我设法用两个简单的 类 重新创建了你的确切异常,它们的实例形成了一个循环引用,就像你的情况一样。
用户:
public class User {
private long id;
private Ticket ticket;
public User(long id) {
this.id = id;
}
//getters and setters
}
门票
public class Ticket {
private long id;
private User user;
public Ticket(long id) {
this.id = id;
}
//getters and setters
}
设置:
User user = new User(1);
Ticket ticket = new Ticket(2);
user.setTicket(ticket);
ticket.setUser(user);
List<User> users = Arrays.asList(user, user, user);
实例相互引用到无穷大,就像你的情况一样。这在 java 中完全有效,但在 json 中很难表示。根据我直接添加集合的测试,导致 Exception in thread "main" org.json.JSONException: JavaBean object contains recursively defined member variable of key "ticket"
.
JSONObject jsonObject = new JSONObject();
jsonObject.put("users", users);
System.out.println(jsonObject);
jsonObject.put(key, collection)
从集合创建 json 数组,但由于某些原因无法处理集合元素中的循环引用。
修复它的解决方法 是手动创建 JSONArray
,然后迭代集合,手动添加每个元素 JSONArray。然后在JSONObject
.
JSONArray jsonArray = new JSONArray();
users.forEach(jsonArray::put);
JSONObject jsonObject = new JSONObject();
jsonObject.put("users", jsonArray);
System.out.println(jsonObject);