Reputation: 33
I'm trying to do my first JEE application with rest api and hibernate. I dont know how to do it in proper way. I mean that I have entity User
@Entity
@XmlRootElement
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String username;
private String password;
private String email;
private LocalDateTime lastDateOfLogin;
@OneToMany(fetch=FetchType.LAZY)
private List<Post> posts = new ArrayList<>();
@OneToMany(fetch=FetchType.LAZY)
private List<Comment> comments = new ArrayList<>();
@OneToMany(fetch=FetchType.LAZY)
private List<Like> likes = new ArrayList<>();
@OneToMany(fetch=FetchType.LAZY)
private List<User> followers = new ArrayList<>();
@OneToMany(fetch=FetchType.LAZY)
private List<User> following = new ArrayList<>();
and I have UserResource method to get one user
@GET
@Path("{id}")
public User getUser(@PathParam("id") long id)
{
return userService.getOne(id);
}
Now my problem is that when I'm trying to get one user I'm getting exception org.hibernate.LazyInitializationException - of course I know why but question is how to do this get it in proper way. In this @GET I don't need this OneToMany collections because when I want E.g user posts I will call user/1/posts url and I will receive all user posts.
How to develop this kind of applications? Should I delete relations from user entity and just search in database posts of user when I need them? Or maybe there is another solution for it?
Upvotes: 0
Views: 969
Reputation: 21163
If that particular endpoint is only interested in the basic details about the user and none of the associations your database model has to other objects in your system, you need to somehow prevent the serialization process from looking at those attributes.
If it is a field that you want to always be ignored, you could annotate it with @XmlTransient
, but this is a decision that is determined at build time and cannot be modified at runtime. For situations where you need to dynamically influence the serialization step, you can either look at these two articles:
Another alternative would be to modify your service to return a class instance for that specific view that only contains the attributes you want to be marshalled into the output XML. This can easily be accomplished with a JPA select new
query like:
SELECT new com.company.app.BasicUser(u.userName, other attributes) FROM User u
WHERE u.id = :id
Now your XML marshalling would be based on BasicUser
and not your domain entity User
, where that BasicUser
doesn't have any of the associations or attributes that you don't wish to have serialized for that specific view.
Upvotes: 1