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