为什么Hibernate HQL能够正常工作,但Criteria没有?

问题描述:

我有一个简单的模型,它只是一对多关系链:国家 - <城市 - <街道 表格被映射为实体并作为地图返回。为什么Hibernate HQL能够正常工作,但Criteria没有?

下面的试验方法是生产奇怪的结果:

public static void main(String[] args) { 
    Session session = HibernateSessionFactory.getSession(); 

    List<Map<String, Object>> results = null; 

    //Query using HQL and print results 
    System.out.println("FROM HQL ====================="); 
    String hql = "from Street where City.Country.countryid = 1";   
    Query query = session.createQuery(hql); 
    results = query.list(); 
    for(Map<String, Object> row : results) { 
     System.out.println(row); 
    } 

    //Query using Criteria and print results 
    System.out.println("FROM CRITERIA ================"); 
    Criteria criteria = session.createCriteria("Street"); 
    criteria.add(Restrictions.eq("City.Country.countryid", 1)); 
    results = criteria.list(); 
    for(Map<String, Object> row : results) { 
     System.out.println(row); 
    } 
} 

它使用HQL的顶块按预期方式工作,但底部块翻倒:

输出:

FROM HQL ===================== 
{streetname=Mayfair, [email protected], $type$=Street, streetid=1} 
{streetname=Park Lane, [email protected], $type$=Street, streetid=2} 
{streetname=Bond Street, [email protected], $type$=Street, streetid=3} 
{streetname=Old Kent Road, [email protected], $type$=Street, streetid=4} 
FROM CRITERIA ================ 
Exception in thread "main" org.hibernate.QueryException: could not resolve property: City.Country.countryid of: Street 
    at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:67) 
    at org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:82) 
    at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:54) 
    at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1367) 
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:457) 
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumnsUsingProjection(CriteriaQueryTranslator.java:417) 
    at org.hibernate.criterion.SimpleExpression.toSqlString(SimpleExpression.java:68) 
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:357) 
    at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:113) 
    at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:82) 
    at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:91) 
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1578) 
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306) 
    at com.bar.foo(Main.java:33) 

我看不出为什么HQL可以解析City.Country.countryid,但是Criteria(Restrictions)不能。

我错过了一些明显的东西吗?

因为您对hql查询使用了错误的语法。 几个缺点:

  • Street.class而不是 “一条街”
  • 缺少别名
  • 使用国家,而不是直接country.id

试试这个:

Criteria criteria = session.createCriteria(Street.class) 
.createAlias("city", "ci") 
.add(Restrictions.eq("ci.country", country)) 

有关更多详细信息,请参阅hibernate reference

+0

谢谢! 我不能使用Street.class,因为我没有Street.class。在我的应用程序中一切都是动态然而,别名的使用似乎有所帮助。 对于“路径”的每个部分,我可以创建一个别名,如下所示: criteria.createAlias(“City”,“ci”); (限制.eq(“co.countryid”,1); 这似乎工作。 – Memran