【问题标题】:how to return criteria Distinct Result如何返回标准不同的结果
【发布时间】:2015-06-18 21:35:36
【问题描述】:

我有具有 onetomany 和 manytoone 关系的 Bill 和 Bill_Details。我在获取账单清单方面需要帮助。

波乔

比尔

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

注意:

--> 账单表包含单行

--> BillDetails 表包含此 BillId 的四行

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

预期输出:

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

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

如何通过 Hibernate criteria Query 得到这个?请帮忙

【问题讨论】:

    标签: java hibernate annotations projection hibernate-criteria


    【解决方案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
    

    【讨论】:

    • 我需要通过投影来实现,因为我在 com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:899) 的 com.google.gson.internal 的 JSON 中有问题。 bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)"。通过使用预测,错误消失了。请帮助解决此错误。
    猜你喜欢
    • 2016-02-14
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 2019-01-18
    • 2012-11-30
    相关资源
    最近更新 更多