2

I have some class User which has one to many relation to LoginSession class (I have a collection of LoginSessions in my User class).

@Entity(name="T_User")
public class User() 
{
   ....
     @OneToMany(fetch=FetchType.LAZY, mappedBy="user", cascade=CascadeType.ALL)
     @Fetch(FetchMode.SELECT)
     @JsonIgnore
     private Set<LoginSession> userLoginSession;
   ....
 }

Here is the LoginSession class:

@Entity(name="T_LoginSession")
public class LoginSession extends BasicDTO
{

    @ManyToOne
    @JoinColumn(name="userId")  
    protected User user;
    ...

And I have this Criteria:

Criteria crit = session.createCriteria(User.class);
crit.setFetchMode("loginSession", FetchMode.JOIN);
crit.createAlias("userLoginSession", "session");
crit.add(Restrictions.eq("session.token", sessionToken));
crit.setMaxResults(1);
crit.setFirstResult(0);
crit.setFetchSize(1);

The problem is that the fetching is always Lazy. How can I make it to be Eager (via criteria and not via attribute annotation)?

Note:
If I am adding @Fetch annotation above the private Set<LoginSession> userLoginSession the response fetching as set in the annotation (I wont it to be customised by the criteria setFetchMode).

Are the names of the fields (the first parameter of the setFetchMode method) correct?

Question: Is this bug related to my issue?

vlio20
  • 8,955
  • 18
  • 95
  • 180

4 Answers4

5

as noted here you can not filter and eager fetch a collection at the same time. you can solve it with a correlated subquery:

DetachedCriteria subquery = DetachedCriteria.For(User.class)
    .createAlias("userLoginSession", "session")
    .add(Restrictions.eq("session.token", sessionToken))
    .setFirstResult(0)
    .setMaxResults(1)     // assuming token is unique otherwise this won't restrict users but loginsessions
    .setProjection(Projections.id());

Criteria crit = session.createCriteria(User.class)
    .add(Subqueries.propertyIn("id", subquery)
    .setFetchMode("userLoginSession", FetchMode.JOIN);

Note: this is text editor code of the top of my head. Methodnames may vary

Community
  • 1
  • 1
Firo
  • 30,626
  • 4
  • 55
  • 94
1

Try:

 Criteria crt = session.createCriteria(User.class);
 crt.setFetchMode("sessions", FetchMode.JOIN);
Alexey Semenyuk
  • 3,263
  • 2
  • 32
  • 36
1

Try following

Criteria crit = session.createCriteria(User.class);
crit.setFetchMode("session.userId", FetchMode.EAGER);
User myThingy = (User)crit.uniqueResult();
Darshan Lila
  • 5,772
  • 2
  • 24
  • 34
1

Try setting the jointype on the alias:

Criteria crit = session.createCriteria(User.class);
crit.createAlias("userLoginSession", "session", Criteria.INNER_JOIN);
crit.add(Restrictions.eq("session.token", sessionToken));
crit.setMaxResults(1);
crit.setFirstResult(0);
crit.setFetchSize(1);
Marius
  • 3,043
  • 1
  • 15
  • 24
  • this is deprecated :( – vlio20 Sep 17 '14 at 17:35
  • What is deprecated? In the stable release, you can use createAlias(String associationPath, alias, joinType) (http://docs.jboss.org/hibernate/stable/core/javadocs/org/hibernate/Criteria.html#createAlias(java.lang.String, java.lang.String, org.hibernate.sql.JoinType)) – Marius Sep 18 '14 at 09:04
  • I am using hibernate 4 and eclipse indicates that is deprecated. Can you look at the names I provided as strings to setFetchingMethod? – vlio20 Sep 18 '14 at 09:18