简体   繁体   English

使用Hibernate Criteria加入而不使用“限制别名”

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM