我有一个具有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));
}
答案 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"));