2009-11-12 68 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