【问题标题】:Hibernate Criteria Question休眠标准问题
【发布时间】:2011-08-13 07:31:28
【问题描述】:

假设我有两个 Hibernate POJO:Customer 和 Order。 Order 表具有三个相关列:customerId、totalItemsSold 和 totalCost。 Customer 表包含以下列:customerId、firstName、lastName 和 city。

我已经在 Order 和 Customer 表之间进行了多对一映射。我的订单 POJO 包含一个客户对象。我想做以下条件查询:

DetachedCriteria crit = DetachedCriteria.forClass(Order.class);
crit.add(Restrictions.eq("customer.city", "Chicago"));
getHibernateTemplate().findByCriteria(crit);

这总是抛出以下异常:

org.springframework.orm.hibernate3.HibernateQueryException: could not resolve property: customer.city of: Order

如何使用 Criteria 根据客户所在城市搜索订单?我的订单 pojo 确实包含一个名为“Customer”的客户对象,并带有适当的 getter 和 setter .....

根据要求编辑(订单/客户类别):

public class Customer {
     private Integer customerId;
     private String firstName;
     private String lastName;
     private String city;

     public Integer getCustomerId() { return customerId; }
     public void setCustomerId(Integer customerId) { this.customerId = customerId; }
     public String getFirstName() { return firstName; }
     public void setFirstName(String firstName) { this.firstName = firstName; }
     public String getLastName() { return lastName; }
     public void setLastName(String lastName) { this.lastName = lastName; }
     public String getCity() { return city; }
     public void setCity(String city) { this.city = city; }
}

public class Order { 
     private Customer customer;
     private Integer totalItemsSold;
     private Integer totalCost;

     public Customer getCustomer() { return customer; }
     public void setCustomer(Customer customer) { this.customer = customer; }
     public Integer getTotalItemsSold() { return totalItemsSold; }
     public void setTotalItemsSold(Integer totalItemsSold) { this.totalItemsSold = totalItemsSold; }
     public Integer getTotalCost() { return totalCost; }
     public void setTotalCost(Integer totalCost) { this.totalCost = totalCost; }
}

这是 Order 类的 hbm 映射(包含 Customer 和 Order 之间的映射):

<many-to-one name="customer" class="Customer" column="customerId" />

【问题讨论】:

  • 您可以发布您的订单和客户代码吗?
  • @Jeff - 他们已添加到我的帖子中
  • @David - 除了查询、异常消息和 POJO 代码之外,还请始终发布相关实体的完整 Hibernate 映射。谢谢

标签: hibernate criteria


【解决方案1】:

您发布的内容看起来不错。也许你的 hbm 文件有错误?

如果没有看到完整的 hbm,我很想明确地告诉你关于客户关系的独立标准:

crit.createAlias("customer", "customer"); 

【讨论】:

  • 有趣....添加别名确实让我可以根据客户对象进行查询,但现在结果重复了。例如,Bob 在 1 月 1 日、2 月 1 日和 3 月 1 日下订单。我得到了 3 份 1 月 1 日的订单、3 份 2 月 1 日的订单和 3 份 3 月 1 日的订单。很奇怪。有什么想法吗?
  • 添加 crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 修复了重复问题。
  • 听起来像是笛卡尔积问题。在这种情况下,这不是 Hibernate 问题,而是您的查询逻辑的问题。很难准确说出问题出在哪里,因为您的实体似乎与您的描述不匹配(没有订单日期)并且您的 hbm 没有发布(这将显示其他多对一关系和获取类型) .急切地获取多种集合类型通常是重复行的罪魁祸首。
  • IIRC,DISTINCT_ROOT_ENTITY 只是掩盖了你的问题。因为它是一个结果转换器,重复的行仍然从数据库返回,但随后 Hibernate 将它们过滤掉。这是一个问题有两个原因:它表明您的查询不正确,并且它为不正确的连接给数据库带来了不必要的负载。随着这些表的增长,这可能会导致性能下降
  • 我想我已经猜到了问题所在。当我们使用 crit.createAlias("customer", "customer") 时,hibernate 可能会进行全连接(类似于 select * from customer, order)。我将如何分配对 createAlias 的限制?有点像 crit.mustEqual("customerId", "customerId") 强制 customerId 值相等(如 select * from customer inner join order on customer.customerId = order.customerId)?
【解决方案2】:

如果您只是按 customerId 搜索,那么您所拥有的:

DetachedCriteria crit = DetachedCriteria.forClass(Order.class);
crit.add(Restrictions.eq("customer.customerId", 12));
getHibernateTemplate().findByCriteria(crit);

可能会奏效。否则 Jeff 和上面提到的其他人,你必须像提到的那样加入 Customer 表

crit.createAlias("customer", "customer"); 

【讨论】:

    【解决方案3】:

    您的 Order 类中的 Customer 实例变量是否称为 customer 或 customerId?

    【讨论】:

    • 客户对象名为Customer,但主键名为customerId。
    猜你喜欢
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 2011-10-09
    • 2012-12-24
    相关资源
    最近更新 更多