I'm using TomEE 9.0.12 with Hibernate 5.3.7 and I am currently getting a stackoverflow exception due to json recursiveness. Note that I am not using jackson, and ideally don't want to, but the standard that comes with TomEE+: org.apache.johnzon.
The exception:
Caused by: java.lang.StackOverflowError
at org.apache.johnzon.mapper.Mappings.findOrCreateClassMapping(Mappings.java:340)
at org.apache.johnzon.mapper.MappingGeneratorImpl.doWriteObjectBody(MappingGeneratorImpl.java:240)
Here is my User.java class:
import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
* A user
*/
@Entity
@Table(name = "users")
public class User implements Serializable {
private static final long serialVersionUID = -9012412584251217L;
// TODO: 16/12/2018 they keep nesting each other: { user { posts { user { posts } } } }
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "username")
private String username;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "salt")
private String salt;
@OneToMany(mappedBy = "user")
private Set<Post> posts = new HashSet<>();
/**
* Constructs an empty user (for persistence purposes)
*/
public User() {}
// Setters and getters removed for convenience
}
And here is my Post.java
import javax.persistence.*;
import java.io.Serializable;
/**
* Project created by ExpDev
*/
@Entity
@Table(name = "posts")
public class Post implements Serializable {
private static final long serialVersionUID = -9887234238952234L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@Column(name = "data")
private String data;
/**
* Constructs an empty post (for persistence purposes)
*/
public Post() {}
// Setters and getters removed for convenience
}
The issue
The issue is that they will keep referring back to each other. User will refer to posts, which will refer back to the user, which will again refer to posts-- and so the evil circle continues.
I know that I can use org.apache.johnzon's annotation @JsonbTransient on "user" in User.java to make it not serialize it, but that makes so that it won't ever show (which I want, but conditionally). Why do I want it like this?
Because, let's say GET /users/1 is accessed, 1 being the id of the user, I want to show all the user's posts (or at least the ID of them), but don't want it to refer back to the user (nested user inside post inside user).
However, if GET /api/posts/3, 3 being the id, I want it to show the user which made the post, but not the posts again inside the user.
So basically, the annotations must be conditional in a way, and specific. Currently, this is how I am retrieving and showing the user (framework automatically converts returned object to JSON when the method is accessed).
@GET
@Path("/{id}")
public User get(@PathParam("id") Long id) {
// Find the user and return them
return HiberUtil.getSession().get(User.class, id);
}
Thank you in advance! I have searched for 5 hours but no solutions or reading material have solved my problem.