Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate OneToMany bi-directional relation is slow

I have Sessions and Users classes with following bi-directional OneToManymapping(generated with hibernate reverse engineering tool):

public class Users {
    @OneToMany(fetch=FetchType.LAZY, mappedBy="users")
    public Set<Sessions> getSessionses() {
        return this.sessionses;
    }
}

public class Sessions {
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="USER_ID")
    public Users getUsers() {
        return this.users;
    }
}

And here is my code which creates new session for user:

Session s = ...;
Users user = (Users) s.createCriteria(Users.class)
             ./*restrictions...*/.uniqueResult();
Sessions userSession = new Sessions();
userSession.setUsers(user);
s.save(userSession);
user.getSessionses().add(userSession); // here getSessionses() has 2k records

User has 2k sessions and therefore last line is very slow.

How can I link session with user without fetching whole sessions collection ?

like image 410
Oleksandr.Bezhan Avatar asked May 15 '13 09:05

Oleksandr.Bezhan


2 Answers

Have a look at Hibernate's extra-lazy loading feature. You enable that by annotating your collection with @LazyCollection(LazyCollectionOption.EXTRA). There is this example to look at, and there's Set used in this one.

public class Users {
    @OneToMany(fetch=FetchType.LAZY, mappedBy="users")
    @LazyCollection(LazyCollectionOption.EXTRA)
    public Set<Sessions> getSessionses() {
        return this.sessionses;
    }
}
like image 142
Balázs Németh Avatar answered Sep 28 '22 08:09

Balázs Németh


I'm not certain if hibernate would add this connection both ways but instead of adding a Session to a User set the User of a Session. This way you don't have to load every session.

like image 24
Lukas Eichler Avatar answered Sep 28 '22 07:09

Lukas Eichler