azxcqqq
azxcqqq

Reputation: 33

Jax-RS - java rest api and hibernate

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

Answers (1)

Naros
Naros

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:

  1. How to Conditionally serialize with JAXB or Jackson
  2. Jacksons JsonView or MOXy's external mapping-files

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

Related Questions