Hibernate Query Criteria for mappings involving inheritance

Lets say that class 'X' is mapped to table 'X' class 'A' is mapped to Table 'A' and Class 'B is mapped to table 'B'.

Table X Structure:(X_ID, some other columns Table A Structure:(A_Id,X_Id, some other columns) Table B Structure:(A_Id, some other columns)...Table B also has A_Id

Class 'B' extends class 'A'. We have the mapping files for both of them as:

Class 'A' Parent Mapping file:

@Entity
@Table(name = 'A')
@Inheritance(stratergy=InheritanceType.Joined)
public abstract class A {
@Id @Clumns(name = "A_Id)
@GeneratedValue
protected Long aId;
-- some more A specific fields
}

Class 'B' Mapping file:

@Entity
@Table(name= 'B')
Public class B extends A{
---- B specific fields
}

Now, I have a SQL Query as below that I need to write using hibernate criteria API.

select * from X
INNER JOIN A 
ON X.id = A.id
INNER JOIN B
ON A.id = B.id
where B.name = 'XYZ'
   and B.Sex = 'M'

I have come up with:

Criteria c = session.createCriteria(x.class, "x");
                    .createAlias("x.a", "a")
                    .createAlias("a.b", "b")          
                    .add(Restrictions.eq("b.sex", "M"))
                    .add(Restrictions.eq("b.name", "XYZ"));

But, if we check the mapping file, there is no direct reference of B in A. Hence hibernate throws out "B not related to A" entity.

Is there any way this inheritance can be mapped in query crteria


You shouldn't need to reference A at all in your criteria, or use any aliases.

Criteria c = session.createCriteria(B.class);
                    .add(Restrictions.eq("sex", "M"))
                    .add(Restrictions.eq("name", "XYZ"));

will give you the result you need.

Because of the InheritanceType.Joined , this will probably produce SQL that includes a join to the the A table (something close to the sql you show), but it isn't necessary to specify that join in the criteria.

The things that look like columns in the criteria are actually (reflective) references to fields in your Java objects. Hibernate figures out the columns to put in the sql from your annotations, and should the join to the A table if it's needed based on the inheritance annotation.

To be sure of this in your context, and to understand all this a bit better, I'd advise trying it and turning on logging of the generated sql as described in this answer to another SO hibernate question.


Try this way: Criteria rootCrit = session.createCriteria(A.class); rootCrit.createAlias("B", "B"); rootCrit.add(Restrictions.eq("B.sex", "M")); rootCrit.add(Restrictions.eq("B.name", "XYZ"));

链接地址: http://www.djcxy.com/p/37054.html

上一篇: JPA本机查询结果返回重复的子对象

下一篇: Hibernate查询条件涉及继承的映射