在Hibernate中,如何在未映射关系时加入?

时间:2015-10-02 15:52:14

标签: hibernate

以下是我的域名模型的摘录,其文本版本为“我有合同,客户,合同客户和发票。发票可以直接链接到客户,也可以链接到合同”。

<class name="Invoice">
  <many-to-one class="Contract" />
  <many-to-one class="Client" />
</class>

<class name="Contract">
  <set table="ContractClient" fetch="select" lazy="true">
    <one-to-many class="ContractClient" />
  </set>
</class>

<class name="ContractClient">
  <many-to-one class="Contract" fetch="select" />
  <many-to-one class="Client" cascade="none" fetch="select" />
</class>

<class name="Client">
  <set table="ContractClient" fetch="select" lazy="true">
    <one-to-many class="ContractClient" />
  </set>
</class>

我有兴趣获取属于客户的发票清单,包括直接链接的发票和客户为其一方的合同。我有以下(有效):

return getCurrentSession().createCriteria(Invoice.class)
    .createAlias("contract", "contract", JoinType.LEFT_OUTER_JOIN)
    .createAlias("contract.contractClients", "contractClient", JoinType.LEFT_OUTER_JOIN)
    .add(Restrictions.or(
        Restrictions.eq("client.id", id),
        Restrictions.eq("contractClient.client.id", id)))
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
    .list();
}

但是,生成的SQL存在很大的性能问题,因为(未显示)Contract有许多1:1的表和大量的fetch = join查找。此外,OR类杀死它。因此,我已经采用了针对这两种类型的单独查询方法(直接链接到客户的发票,以及通过合同链接到客户的发票)。我很难想出第二件作品。

由于JOINS和选定列的爆炸,我想避免加入合同。如果我自己用SQL编写,我会使用:

SELECT 
    *
FROM
    Invoice i
        LEFT OUTER JOIN ContractClient c ON i.contractId=c.contractId 
WHERE 
    c.clientId=?

但是,我在Invoice和ContractClient之间没有Hibernate映射,所以我要么必须通过Contract(我不想要),要么这样做(产生子选择):

DetachedCriteria detachedCriteria = DetachedCriteria.forClass(ContractClient.class)
    .add(Restrictions.eq("client.id", id))
    .setProjection(Projections.property("contract"));
return getCurrentSession().createCriteria(Invoice.class)
    .add(Property.forName("contract").in(detachedCriteria))
    .list();

生产:

SELECT
    *
FROM
    Invoice this_ 
WHERE
    this_.contractId IN (   SELECT
                            this_.contractId AS y0_ 
                        FROM
                            ContractClient this_ 
                        WHERE
                            this_.contractClientId=?)

有没有办法让Hibernate生成更直接的JOIN?

0 个答案:

没有答案