如何返回标准Distinct Result

时间:2015-04-13 14:18:30

标签: java hibernate annotations projection hibernate-criteria

我有Bill和Bill_Details的onetomany和manytoone Relationship。获得Bill List需要帮助。

POJO的

比尔

@OneToMany(cascade={CascadeType.ALL},fetch = FetchType.EAGER)
@JoinColumn(name = "bill_id")
private Set<BillDetails> billDetails = new HashSet<BillDetails>();

BillDetails

@ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@JoinColumn(name = "bill_id")
private Bill billId;

我正在使用Projections从List中获取Bill值。

DaoHibernate

@Transactional
public List<Bill> getbillDetailsByBillId(String billId) {
    Criteria cr = null;
    try {
        cr = getSession().createCriteria(Bill.class,"bill")
                .createAlias("bill.billDetails","billDetails")
                .setProjection(Projections.projectionList()
  // I tried    .setProjectionProjections.distinct(Projections.projectionList()
                        .add(Projections.property("billNo"),"billNo")
                        .add(Projections.property("billDetails.amount"),"billDetails.amount")
                        .add(Projections.property("billDetails.rate"),"billDetails.rate"))                          
                        .add(Restrictions.eq("id", billId))
                        .setResultTransformer(new AliasToBeanNestedResultTransformer(Bill.class));

    } catch (Exception e) {
        System.out.println("Get bill DetailsByBillId Error----------"+e);
        e.printStackTrace();
    }
    System.out.println(cr.list().size());
    return cr.list();
}

注意:

- &gt; Bill表包含单行

- &gt; BillDetails表包含此BillId的四行

我的条件查询返回四个对象而不是单个对象。我也尝试了不同的功能。

预期输出:

我需要包含BillDetails对象(4个值)的单个对象。 ie.I用下面的样本Json格式解释

{billNo:231,
    billDetails[{amount:100,rate:1}{amount:200,rate:2}
     {amount:300,rate:30}{amount:400,rate:4}] }

如何通过Hibernate条件查询得到这个?请帮忙

1 个答案:

答案 0 :(得分:1)

首先,您的映射不正确。你有一个双向关联,其中一方(一方)必须是一方的反面:

@OneToMany(mappedBy = "billId", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<BillDetails> billDetails = new HashSet<BillDetails>();

您还应该将字段billId重命名为bill,因为它包含的是帐单,而不是帐单ID。

现在,您的查询问题在于您无缘无故地使用投影。使用投影时,您故意选择返回包含单个列的行。并且由于SQL查询返回4行,您将获得4个账单:每行一个。

通过使用Criteria查询而不是HQL,您也会使您的生活变得更加复杂,而HQL更适合这种简单的静态查询。

但即使是HQL查询也没用,因为您只想从其ID中获取帐单。你所需要的只是

Bill bill = (Bill) session.get(Bill.class, billId);

这将收到账单,因为您选择将OneToMany关联作为EAGER,它也会立即加载其账单明细。

如果您没有建立EAGER关联(并且您应该将其保留为LAZY),则可以使用此简单的HQL查询来加载包含其详细信息的帐单:

select distinct b from Bill bill 
left join fetch bill.billDetails 
where bill.id = :billId