2009-11-12 70 views
25

我遇到了Hibernate条件的问题。我试图在查看返回的类的成员对象的id时创建一个Criteria。Java/Hibernate:无法使用嵌套对象标准解析属性

例如:

Criteria crit = session.createCriteria(Enquiry.class); 
crit.add(Expression.eq("lecture.admin.id", userId));` 

这样做的结果是一个例外:
org.hibernate.QueryException: could not resolve property: lecture.admin.id of: xxx.yyy.Enquiry

Enquiry类确实包含演讲变量,这反过来又包含admin变量。我试过使用lecture.id,这工作正常。

您可以像这样在对象层次结构中层数的数量是否有限制?

谢谢!

代码片段:

public class Lecture extends TransferItem { 
    private User admin; 
    public User getAdmin() { 
    return admin; 
    } 
} 

'用户' 类扩展Person类,这反过来又延伸的Item类,其具有getId()方法:

public Integer getId() { 
    if (id != null) { 
    return id; 
    } 
    return TransferBean.NOT_SET; 
} 

从Hibernate映射XML :

<class name="User" table="user"> 
    <id column="user_id" name="id"> 
    <generator class="increment"/> 
    </id> 
    ... 

<class name="Lecture" table="lecture"> 
    <many-to-one class="User" column="user_fk" lazy="false" name="admin"/>` 

这是在user表:

mysql> show columns from user; 
+-----------------+--------------+------+-----+---------+-------+ 
| Field   | Type   | Null | Key | Default | Extra | 
+-----------------+--------------+------+-----+---------+-------+ 
| user_id   | int(11)  | NO | PRI |   |  | 
| firstname  | varchar(50) | YES |  | NULL |  | 
| lastname  | varchar(50) | YES |  | NULL |  | 
| signature  | varchar(16) | YES |  | NULL |  | 
| email_signature | varchar(256) | YES |  | NULL |  | 
| password  | varchar(32) | YES |  | NULL |  | 
| phone   | varchar(16) | YES |  | NULL |  | 
| email   | varchar(255) | YES | UNI | NULL |  | 
| lecturer_fk  | int(11)  | YES | MUL | NULL |  | 
| access   | int(11)  | YES |  | NULL |  | 
| deleted   | tinyint(1) | YES |  | NULL |  | 
+-----------------+--------------+------+-----+---------+-------+ 
11 rows in set (0.02 sec)` 

回答

68

您不能直接在Criteria API中使用嵌套路径(与HQL不同)。相反,你需要创建嵌套的标准实例或每个“entity.property”对定义的别名从第一个非根实体:

Criteria criteria = session.createCriteria(Enquiry.class) 
.createAlias("lecture", "l") 
.createAlias("l.admin", "a") 
.add(Restrictions.eqProperty("a.id", userId)); 

需要注意的是,因为它属于最先属性没有前缀根实体(Enquiry),其他则以前一级别名作为前缀。详情是in the documentation

另请注意,id是一个特殊的财产,当涉及到协会;在你的情况下,user_fk是位于lecture表中的一列。它应该,因此,才有可能(前提是你已经发布的映射是准确的)改写上述标准为:

Criteria criteria = session.createCriteria(Enquiry.class) 
.createAlias("lecture", "l") 
.add(Restrictions.eqProperty("l.admin.id", userId)); 

从而消除额外加入。

+0

啊,非常好的一点。 – Henning 2009-11-12 17:20:39

+0

像往常一样具有启发性@ ChssPly76 – 2009-11-12 19:14:55

+0

这工作很好。十分感谢你的帮助。 – Malakim 2009-11-13 06:38:53

2
Criteria crit = session.createCriteria(Enquiry.class) 
crit.createAlias("lecture.admin", "lectureAdmin"); 
crit.add(Expression.eq("lectureAdmin.id", userId)); 

当你去了对象图太深您确实可以打的问题。我通常通过创建一个别名来解决这个问题,如上所示。

+1

我想这一点,但后来我打了一个SQLGrammarException代替:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 致未知列在“where子句” 任何想法“lectureadm1_.user_id”? – Malakim 2009-11-12 15:03:37

+0

这看起来像来自数据库的错误,表示“user”表中没有“user_id”列。你确定你的数据库表有这个列吗?也许数据库中的列也被称为“id”,如果这是你的hibernate映射的问题。 – 2009-11-12 15:31:21

+0

我将用户数据库表添加到问题 谢谢! – Malakim 2009-11-12 16:29:31