Atais
Atais

Reputation: 11275

Hibernate 4 entities and Jackson 2, lazy loading issue

so I read this topic: deserialize lazy loading in hibernate and jackson

and I would like to achieve similar - or actually - the same as previous author. However for two days now I am stuck and I do not understand my mistake.

So f.e I have this UserModel and AuthoritiesModel class for Hibernate entity:

UserModel:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "username")
@JsonAutoDetect
@Entity
@Table(name = "users")
public class UserModel implements Serializable, Cloneable {

    private static final long serialVersionUID = 8019466778684575940L;

    @Id
    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    @Column(name = "enabled")
    private Boolean enabled;

    @Column(name = "email")
    private String email;

    @Column(name = "name")
    private String name;

    @Version
    @Column(name = "VERSION")
    private int version;

    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY, targetEntity = AuthorityModel.class)
    private List<AuthorityModel> authorities = new ArrayList<AuthorityModel>();

    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY, targetEntity = MessageModel.class)
    private List<MessageModel> messages = new ArrayList<MessageModel>();

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = StatusModel.class)
    @JoinColumn(name = "status")
    private StatusModel status;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "meeting_user", joinColumns = { @JoinColumn(name = "username", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "id_meeting", nullable = false, updatable = false) })
    private List<MeetingModel> meetings = new ArrayList<MeetingModel>();

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "contact_user", joinColumns = @JoinColumn(name = "username", nullable = false, updatable = false), inverseJoinColumns = @JoinColumn(name = "contact_username", nullable = false, updatable = false))
    private List<UserModel> contacts = new ArrayList<UserModel>();

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "contact_user", joinColumns = @JoinColumn(name = "contact_username", nullable = false, updatable = false), inverseJoinColumns = @JoinColumn(name = "username", nullable = false, updatable = false))
    private List<UserModel> contactOf = new ArrayList<UserModel>();

AuthorityModel:

@JsonAutoDetect
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@Entity
@Table(name = "authorities")
public class AuthorityModel extends BaseEntity implements GrantedAuthority {

    private static final long serialVersionUID = -3950709468104459415L;
    public static final String ROLE_USER = "ROLE_USER";
    public static final String ROLE_ADMIN = "ROLE_ADMIN";

    @Column(name = "authority")
    private String authority;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = UserModel.class)
    @JoinColumn(name = "username")
    private UserModel user;

And I am using Hibernate4Module to manage the entities but if I leave h.configure(Feature.FORCE_LAZY_LOADING, false); I end up with all the collections empty (null) like:

{
   "username":"rod",
   "password":"e97673c55fc4f2af8bf2122333df24ac",
   "enabled":true,
   "email":null,
   "name":null,
   "version":1,
   "authorities":null,
   "messages":null,
   "status":null,
   "meetings":null,
   "contacts":null,
   "contactOf":null
}

and if I make it Eager or h.configure(Feature.FORCE_LAZY_LOADING, true); I get my whole database loaded, like this:

{
   "username":"rod",
   "password":"e97673c55fc4f2af8bf2122333df24ac",
   "enabled":true,
   "email":null,
   "name":null,
   "version":1,
   "authorities":[
      {
         "id":"1",
         "version":0,
         "description":null,
         "comment":null,
         "authority":"ROLE_USER",
         "user":"rod"
      }
   ],
   "messages":[
      {
         "id":"1",
         "version":0,
         "description":null,
         "comment":null,
         "message":"TEST",
         "user":"rod",
         "meeting":{
            "id":"1",
            "version":0,
            "description":null,
            "comment":null,
            "users":[
               {
                  "username":"bob",
                  "password":"8ee3086749f7fa95ffe9c4588037cb10",
                  "enabled":true,
                  "email":null,
                  "name":null,
                  "version":1,
                  "authorities":[
                     {
                        "id":"2",
                        "version":0,
                        "description":null,
                        "comment":null,
                        "authority":"ROLE_ADMIN",
                        "user":"bob"
                     },
                     {
                        "id":"3",
                        "version":0,
                        "description":null,
                        "comment":null,
                        "authority":"ROLE_USER",
                        "user":"bob"
                     }
                  ],
                  "messages":[
                     {
                        "id":"2",
                        "version":0,
                        "description":null,
                        "comment":null,
                        "message":"TEST BACK",
                        "user":"bob",
                        "meeting":"1"
                     }
                  ],
                  "status":{
                     "id":"1",
                     "version":0,
                     "description":null,
                     "comment":null,
                     "status":"available",
                     "users":[
                        "bob",
                        "rod"
                     ]
                  },
                  "meetings":[
                     "1"
                  ],
                  "contacts":[
                     "rod"
                  ],
                  "contactOf":[
                     "rod"
                  ]
               },
               "rod"
            ],
            "messages":[
               "1",
               "2"
            ]
         }
      }
   ],
   "status":"1",
   "meetings":[
      "1"
   ],
   "contacts":[
      "bob"
   ],
   "contactOf":[
      "bob"
   ]
} 

Why is it loading everything, not only 1 collection deep? I would like to have the collections only with the ID of the referenced object or something similar, but I cant find the way to do so.

Any help appreciated!

--- to clarify i expect something similar to:

{
   "username":"rod",
   "password":"e97673c55fc4f2af8bf2122333df24ac",
   "enabled":true,
   "email":null,
   "name":null,
   "version":1,
   "authorities":[
      {
         "id":"1",
      }
   ],
   "messages":[
      {
         "id":"1",
      }
   ],
   "status":"1",
   "meetings":[
      "1"
   ],
   "contacts":[
      "bob"
   ],
   "contactOf":[
      "bob"
   ]
} 

Upvotes: 0

Views: 831

Answers (1)

tmarwen
tmarwen

Reputation: 16354

Just remove the fetch = FetchType.LAZY from @JoinColumn annotation for the properties you want to have eagerly loaded and keep it for properties you don't want to fetch (Should be of Collection type).

Upvotes: 1

Related Questions