Issue
I have a query that generates a List
of Tickets
using hibernate like so :
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);
I tried to put the list in a JSONObject :
List allTickets = ticketDao.getTicketsByUserDao(user);
JSONObject jo = new JSONObject();
jo.put("ticket", allTickets);
It throws this exception :
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)
What is a recursivelyDefinedObjectException
? my Google searches always lead to the subject of Recursion & Functions, not the exception.
When debugging, the allTickets
List contains 4 objects like so :
[
[Ljava.lang.Object;@10e63606,
[Ljava.lang.Object;@3c76d000,
[Ljava.lang.Object;@5f5bfd07,
[Ljava.lang.Object;@3a14ab96
]
He's the content of one first object for example :
[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 protected], 00999999999]
Environment :
- Eclipse : Version: 2021-06 (4.20.0) Build id: 20210612-2011
- Java 8
- my JSONOject comes from this dependency
Any help appreciated.
EDIT: Adding Entities
Fetching the Tickets
list is what's causing the problem so .
Ticket
@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;
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;
User
@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;
Response
@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;
Structure
@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;
EDIT 2 :
When debugging I noticed that aStructure
of User
's Ticket
has exception stack trace as content for it's PersistentBag,
What the hell is causing this ?! I checked my Entity definitions and they look alright to me.
Side note
My Ticket
object contains the User
object, which contains a list of the User
s's Ticket
s, and it goes on and on forever, infinite recursion, is this normal ? are my Entity definitions wrong ? how can i fix this ?
Solution
I see you managed to fix it, but i'll add another option for completeness. I managed to recreate your exact exception with two simple classes, whose instances form a circular refference, as in your case.
User:
public class User {
private long id;
private Ticket ticket;
public User(long id) {
this.id = id;
}
//getters and setters
}
Ticket
public class Ticket {
private long id;
private User user;
public Ticket(long id) {
this.id = id;
}
//getters and setters
}
The setup:
User user = new User(1);
Ticket ticket = new Ticket(2);
user.setTicket(ticket);
ticket.setUser(user);
List<User> users = Arrays.asList(user, user, user);
The instances refference each other into infinity, as in your case. That's totally valid in java, but it's hard to represent in json. According to my tests directly adding the collection, causes 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)
creates json array from the collection, but for some reason can't deal with circular refferences in collection elements.
The workaround, which fixed it, was to manually create JSONArray
, then iterate the collection adding each element manually JSONArray. Then add the prepared json array in JSONObject
.
JSONArray jsonArray = new JSONArray();
users.forEach(jsonArray::put);
JSONObject jsonObject = new JSONObject();
jsonObject.put("users", jsonArray);
System.out.println(jsonObject);
Answered By - Chaosfire
Answer Checked By - David Marino (JavaFixing Volunteer)