Java / Hibernate:无法使用嵌套对象条件解析属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1722539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java / Hibernate: Could not resolve property with nested object criterias
提问by Malakim
I'm having problems with a Hibernate criteria. I'm trying to make a Criteria where I look at the id of a member object of the class the query returns.
我在使用 Hibernate 标准时遇到了问题。我正在尝试创建一个 Criteria,在其中查看查询返回的类的成员对象的 id。
For example:
例如:
Criteria crit = session.createCriteria(Enquiry.class);
crit.add(Expression.eq("lecture.admin.id", userId));`
The result of this is an exception:org.hibernate.QueryException: could not resolve property: lecture.admin.id of: xxx.yyy.Enquiry
这样做的结果是一个例外:org.hibernate.QueryException: could not resolve property: lecture.admin.id of: xxx.yyy.Enquiry
The Enquiry
class does contain the lecture variable, which in turn contains the admin variable. I have tried using lecture.id
and that works fine.
该Enquiry
班确实包含讲座变量,又包含了admin变量。我试过使用lecture.id
,效果很好。
Is there a limit to the number of levels you can go down the object hierarchy like this?
您可以像这样沿着对象层次结构向下移动的级别数是否有限制?
Thanks!
谢谢!
Code snippets:
代码片段:
public class Lecture extends TransferItem {
private User admin;
public User getAdmin() {
return admin;
}
}
The 'User' class extends the Person
class, which in turn extends an Item
class, which has the getId()
method:
'User' 类扩展了Person
该类,该类又扩展了一个Item
具有以下getId()
方法的类:
public Integer getId() {
if (id != null) {
return id;
}
return TransferBean.NOT_SET;
}
From the Hibernate mapping XML:
来自 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"/>`
This is the user
table:
这是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)`
采纳答案by ChssPly76
You can't use nested paths directly in Criteria API (unlike HQL). Instead, you need to create nested criteria instances or define aliases on each "entity.property" pair starting with the first non-root entity:
您不能直接在 Criteria API 中使用嵌套路径(与 HQL 不同)。相反,您需要在从第一个非根实体开始的每个“entity.property”对上创建嵌套条件实例或定义别名:
Criteria criteria = session.createCriteria(Enquiry.class)
.createAlias("lecture", "l")
.createAlias("l.admin", "a")
.add( Restrictions.eqProperty("a.id", userId) );
Note that the very first property is not prefixed as it belongs to the root entity (Enquiry
), the others are prefixed with previous level alias. Details are in the documentation.
请注意,第一个属性没有前缀,因为它属于根实体 ( Enquiry
),其他属性以前一级别名为前缀。详细信息在文档中。
Also note that id
is a special property when it comes to associations; in your case user_fk
is a column located in lecture
table. It should, therefore, be possible (provided that the mappings you've posted are accurate) to rewrite the above criteria as:
还要注意,id
当涉及到关联时,这是一个特殊的属性;在您的情况下user_fk
是位于lecture
表中的列。因此,应该可以(前提是您发布的映射是准确的)将上述条件重写为:
Criteria criteria = session.createCriteria(Enquiry.class)
.createAlias("lecture", "l")
.add( Restrictions.eqProperty("l.admin.id", userId) );
thus eliminating extra join.
从而消除额外的连接。
回答by Tendayi Mawushe
Criteria crit = session.createCriteria(Enquiry.class)
crit.createAlias("lecture.admin", "lectureAdmin");
crit.add(Expression.eq("lectureAdmin.id", userId));
You can indeed hit issues when you go down too deep in the object graph. I usually get around this by creating an alias as shown above.
当您在对象图中走得太深时,您确实会遇到问题。我通常通过创建一个别名来解决这个问题,如上所示。