-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Criteria fails on subclasses with common property name
PostPosted: Thu May 29, 2008 10:07 am 
Newbie

Joined: Fri Apr 04, 2008 2:17 pm
Posts: 15
I have a 'User' which may be one of 'LoginUser' or 'SciQuestUser'
Each subclass has a property called 'login'
This property is not shared in the superclass because each class maps to a table and it is the case that the LOGIN column of LoginUser is unique to its table while the LOGIN column of SciQuestUser is unique to ITS table (but a single LoginUser and a single SciQuestUser may have the same login).
Writing a criteria that searches over 'login' on an object that has a ManyToOne reference to the abstract User class creates SQL that arbitrarily does the evaluation for a single subclass

The relevant portions of my classes are:

User
Code:
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@Table(name="USERS")
public abstract class User{
...
}


LoginUser
Code:
@Entity
@Table(name="LOGIN_USERS")
public class LoginUser extends User{
@Column(name="LOGIN")
   private String login;
...
}


SciQuestUser
Code:
@Entity
@Table(name="SCIQUEST_USERS")
public class SciQuestUser extends User{
@Column(name="LOGIN")
   private String login;
...
}



The criteria in question is written over the class Order:
Code:
@Entity
@Table(name="ORDERS")
public class Order{
...
@ManyToOne
   @JoinColumn(name="USER_ID")
   private User user;
...
}



The criteria is being generated as follows:
Code:
DetachedCriteria criteriaOrder= DetachedCriteria.forClass(Order.class);
DetachedCriteria criteriaUser = criteriaOrder.createCriteria("user");
criteriaUser.add(Restrictions.like("login", "%torme%").ignoreCase());




The generated SQL from the criteria looks like:
Code:
select ... from ORDERS order1_, USERS user2_, LOGIN_USERS user2_1_, SCIQUEST_USERS user2_2_ where order1_.USER_ID=user2_.USER_ID and user2_.USER_ID=user2_1_.USER_ID(+) and user2_.USER_ID=user2_2_.USER_ID(+) and lower(user2_1_.LOGIN) like 'torme'



The evaluation of the LOGIN column was only done on the LOGIN_USERS table. The correct query SHOULD be:
Code:
select ... where ... and (lower(user2_1_.LOGIN) like 'torme' or lower(user2_2_.LOGIN) like 'torme')



I think this is a hibernate bug? Or am I doing something wrong in this case


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 29, 2008 10:17 am 
Newbie

Joined: Fri Apr 04, 2008 2:17 pm
Posts: 15
The behavior is a bit inconsistent because the following queries work. This leads me to believe that querying subclass properties of superclass references isn't inherently unsupported:

Code:
DetachedCriteria criteriaOrder= DetachedCriteria.forClass(Order.class);
DetachedCriteria criteriaUser = criteriaOrder.createCriteria("user");
criteriaUser.add(Restrictions.eq("class", bpf.database.userAccounts.LoginUser.class));


and

Code:
DetachedCriteria criteriaOrder= DetachedCriteria.forClass(Order.class);
DetachedCriteria criteriaUser = criteriaOrder.createCriteria("user");
criteriaUser.add(Restrictions.eq("class", bpf.database.userAccounts.SciQuestUser.class));


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 29, 2008 11:22 am 
Newbie

Joined: Fri Apr 04, 2008 2:17 pm
Posts: 15
I got the behavior working correctly, but I'm not sure if this would be considered a 'correct solution' or a workaround. Regardless, this is what I did:

where I HAD:
Code:
DetachedCriteria criteriaOrder= DetachedCriteria.forClass(Order.class);
DetachedCriteria criteriaUser = criteriaOrder.createCriteria("user");
criteriaUser.add(Restrictions.like("login", "%torme%").ignoreCase());


I now HAVE:
Code:
DetachedCriteria criteriaOrder= DetachedCriteria.forClass(Order.class);
DetachedCriteria criteriaUser = criteriaOrder.createCriteria("user");

DetachedCriteria loginCriteria = DetachedCriteria.forClass(LoginUser.class);
      DetachedCriteria sciquestCriteria = DetachedCriteria.forClass(SciQuestUser.class);
      
      loginCriteria.add(Restrictions.like("login", "%torme%").ignoreCase());
      sciquestCriteria.add(Restrictions.like("login", "%torme%").ignoreCase());

      loginCriteria.setProjection(Property.forName("id"));
      sciquestCriteria.setProjection(Property.forName("id"));
      
      criteriaUser.add(
            Restrictions.or(
               Property.forName("id").eq(loginCriteria),
               Property.forName("id").eq(sciquestCriteria)
         ));


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.