使用Hibernate Criteria加入而不使用限制上的Alias

时间:2014-07-24 12:34:01

标签: java mysql sql hibernate hibernate-criteria

我有一个具有70个属性的对象。为了便于使用,我创建了两个对象,一个' main'对象和细节' object,基于自动生成的整数ID的1:1关系。我有一个SEARCH屏幕,允许搜索任何主要属性,为此我为用户输入的内容构建限制对象。有什么好处是我通过遍历字段和建立标准来完成这一切 - 我没有&#39 ; t需要丑陋的代码来专门处理30个属性中的每一个。

现在他们也希望搜索详细信息字段。我之前的屏幕字段迭代代码完美无缺地完成(完成它的全部原因' generic')但是我无法让JOIN工作来查询详细信息字段。

class House {
    Integer houseID;
    String address;
    . . .
    HouseDetails houseDetails;
}

class HouseDetails {
    Integer houseID;
    String color;
    . . .
}

我尝试创建别名并将其添加到条件中:

criteria.createAlias("houseDetails", "houseDetails");

但是我收到了这个错误:

org.hibernate.QueryException: could not resolve property: color of: House

这就是事情 - 我知道如果我使用别名来限制我的限制,这会有效,但我不想知道该字段来自哪个表(House或HouseDetails)。这会破坏所有自动循环代码并为每个字段创建特定代码。

因为只要列名是唯一的,SQL就可以这样做:

select * from house, housedetails where house.houseID = housedetails.houseID 
and color = 'blue';

我想知道如何才能使用标准来实现这一点?

顺便说一下,但与此有关:有没有办法像Java一样对Hibernate HBM.XML映射文件进行内省?我曾多次想要解决这些问题,但从未找到答案。对于上面的问题,如果我可以很容易地找出每个字段包含哪个表,我可以在限制中添加前缀。像这样:

// 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));
}

2 个答案:

答案 0 :(得分:1)

您可以使用方法查找已传递列名的表名。

通过使用SessionFactory.getClassMetaData(),您可以获得有关该课程的所有信息。获得ClassMetaData后,您就可以获得所有属性名称。演示方法如下所示:

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;
    }       
}

答案 1 :(得分:0)

hibernate和Criteria API中的别名机制已经很好地指定了。我建议稍微阅读一下文档。

我认为你想要的是这样的:

Criteria criteria = session.createCriteria(House.class);
criteria.createAlias("houseDetails.color", "houseColor");
criteria.add(Restrictions.eq("houseColor", "red"));