[英]Join using Hibernate Criteria without using Alias on Restriction
I have an object with 70 attributes. 我有一个具有70个属性的对象。 For ease of use I created 2 objects, a 'main' object and a 'details' object, with 1:1 relationship based on an auto-generated integer ID. 为了易于使用,我基于自动生成的整数ID创建了两个对象,分别具有1:1关系的“ main”对象和“ details”对象。 I had a SEARCH screen that allowed searching on any of the main attributes, for which I build Restriction objects for whatever the user typed in. What was nice was that I did this all through iterating through the fields and building criterion - I didn't need ugly code to specifically handle each of the 30 attributes. 我有一个SEARCH屏幕,可以搜索任何主要属性,为此,我可以为用户输入的内容构建Restriction对象。很好的是,我通过遍历字段和构建条件来完成所有这些工作-我没有需要难看的代码来专门处理30个属性中的每个属性。
Now they want to search on the details fields as well. 现在他们也想搜索详细信息字段。 My previous screen-field-iterating code works perfectly with no changes (the whole reason for making it 'generic'), however I cannot get the JOIN to work to query on details fields. 我之前的屏幕字段迭代代码无需更改即可完美运行(将其设为“通用”的全部原因),但是我无法让JOIN来查询详细信息字段。
class House {
Integer houseID;
String address;
. . .
HouseDetails houseDetails;
}
class HouseDetails {
Integer houseID;
String color;
. . .
}
I tried to create an alias and add it to the criteria : 我试图创建一个别名并将其添加到条件中:
criteria.createAlias("houseDetails", "houseDetails");
but I get this error : 但我得到这个错误:
org.hibernate.QueryException: could not resolve property: color of: House
Here's the thing - I know this would work if I prefix my restrictions with the alias name, but I do NOT want to have to know which table (House or HouseDetails) the field comes from. 事情就是这样-我知道如果我在限制条件前面加上别名,这是可行的,但我不想知道该字段来自哪个表(House或HouseDetails)。 That would ruin all the automatic looping code and create specific code for each field. 这将破坏所有自动循环代码,并为每个字段创建特定的代码。
Since SQL can do this as long as the column names are unique : 由于SQL可以做到这一点,只要列名是唯一的即可:
select * from house, housedetails where house.houseID = housedetails.houseID
and color = 'blue';
I'm wondering how can I get this to work using criteria?? 我想知道如何使用标准使它正常工作?
As an aside, but related to this : Is there a way to perform something like Java's introspection on Hibernate HBM.XML mapping files? 顺便说一句,但与此有关:是否有一种方法可以对Hibernate HBM.XML映射文件执行Java的自省? A number of times I've wanted to do this to solve problems but never found an answer. 我曾多次想这样做来解决问题,但从未找到答案。 For the above problem, if I could easily find out which table contained each field, I could add the prefix to the Restriction. 对于上述问题,如果我可以轻松找出哪个表包含每个字段,则可以在“限制”中添加前缀。 Something like this : 像这样的东西:
// Map of search keys (columns) to searching values
for ( String key : parms.keySet() ) {
String val = parms.get(key);
if ( HIBERNATE-SAYS-KEY-IS-FROM-DETAILS-TABLE ) {
key = "houseDetails." + key;
}
criteria.add(Restrictions.eq(key,val));
}
You can make method to find table name for passed column name. 您可以使方法为传递的列名查找表名。
By using SessionFactory.getClassMetaData()
you can get all the information about that class. 通过使用SessionFactory.getClassMetaData()
您可以获得有关该类的所有信息。 Once you have ClassMetaData
then you can get all the property names. 一旦有了ClassMetaData
就可以获取所有属性名称。 An demo method is shown below: 演示方法如下所示:
public String findTableName(String columnName)
{
boolean found=false;
Map<String, ClassMetadata> classMetaData = sessionFactory.getAllClassMetadata();
for (Entry<String, ClassMetadata> metaData : classMetaData.entrySet())
{
String[] propertyNames = metaData.getValue().getPropertyNames();
for (String property : propertyNames)
{
if(property == columnName)
{
return metaData.getKey() + "." + property;
found=true;
break;
}
}
if(found)
break;
}
}
The alias mechanism in hibernate and the Criteria API is pretty well specified. hibernate和Criteria API中的别名机制已经很好地指定了。 I suggest going through the documentation a little a bit. 我建议稍微阅读一下文档。
I think what you want is something like this: 我认为您想要的是这样的:
Criteria criteria = session.createCriteria(House.class);
criteria.createAlias("houseDetails.color", "houseColor");
criteria.add(Restrictions.eq("houseColor", "red"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.