为什么 Hibernate HQL 可以工作,而 Criteria 却不能?

发布于 2024-12-12 22:31:56 字数 3013 浏览 0 评论 0原文

我有一个简单的模型,它只是一对多关系链: Country -<城市 -<街道 表被映射为实体并作为 Map 返回。

以下测试方法产生奇怪的结果:

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, City=org.hibernate.proxy.map.MapProxy@2b12e7f7, $type$=Street, streetid=1}
{streetname=Park Lane, City=org.hibernate.proxy.map.MapProxy@2b12e7f7, $type$=Street, streetid=2}
{streetname=Bond Street, City=org.hibernate.proxy.map.MapProxy@663b1f38, $type$=Street, streetid=3}
{streetname=Old Kent Road, City=org.hibernate.proxy.map.MapProxy@663b1f38, $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(限制)可以't。

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

I have a simple model which is just a chain of one-to-many relationships: Country -< City -< Street
The tables are mapped as entities and are returned as Map.

The following test method is producing odd results:

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

The top block which uses the HQL works as expected, but the bottom block falls over:

Output:

FROM HQL =====================
{streetname=Mayfair, City=org.hibernate.proxy.map.MapProxy@2b12e7f7, $type$=Street, streetid=1}
{streetname=Park Lane, City=org.hibernate.proxy.map.MapProxy@2b12e7f7, $type$=Street, streetid=2}
{streetname=Bond Street, City=org.hibernate.proxy.map.MapProxy@663b1f38, $type$=Street, streetid=3}
{streetname=Old Kent Road, City=org.hibernate.proxy.map.MapProxy@663b1f38, $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)

I can't see why the HQL can resolve City.Country.countryid but Criteria (Restrictions) can't.

Am I missing something obvious?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小苏打饼 2024-12-19 22:31:57

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

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

试试这个:

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

请参阅 hibernate 参考 了解更多详细信息。

Because you used the wrong syntax for the hql query.
several faults:

  • Street.class instead of "Street"
  • Missing alias
  • use country directly instead of country.id

Try this:

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

See the hibernate reference for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文