Hibernate在没有询问的情况下检索多对一

时间:2014-02-24 18:33:44

标签: java sql hibernate one-to-many hibernate-mapping

我们的开发团队遇到了很大的问题。

我们正在使用Hibernate,并且我们有一些实体在两个传递的一对多关系中相关。主对象是一个具有Property实例列表的Group,每个Property包含一个Values列表。

(映射向前)

我们有两个主要问题:

A)在进行HQL查询,Criteria Query或SQLQuery时,JOIN或WHERE子句中应用的条件无关紧要,Hibernate总是为我们检索所有底层对象。例如,如果我使Criteria或SQL只获取Group对象,Hibernate来了(懒惰或不懒惰)获取所有Property和Value实例。我们想要控制它。我们想做左连接并只得到里面没有值的属性(Hibernate删除这些没有值的属性)

B)在进行查询(例如SQL)时,它会在日志中显示我们想要的SQL代码。一切似乎都很完美。但之后它会在列表中显示每个实例而不应用条件,只能通过id获取它们,我们可以保证这一点,因为使用lazy =“true”我们会在日志中看到“加载多对一”查询。

我们可以在hibernate配置,获取模式/策略,映射配置或任何地方做些什么吗?我正在考虑现在进行结果变换器。

如果有人给我一个提示或告诉我在哪里找到解决这个问题的方法,我将不胜感激。我们对如何实现这一点感到困惑,但它必须是一种方式。

提前致谢

查询:

Criteria lstCriterios = this.getSession().createCriteria(CardGroup.class, CARD_GROUP)
            .add(Restrictions.eq(ID_CATEGORY, idCategory));

    lstCriterios.createAlias("listProperty", "listProperty", CriteriaSpecification.LEFT_JOIN);

    if (clusterId != null) {
        lstCriterios.add(Restrictions.or(
                Restrictions.isNull("listPropertyValue" + ".value"),
                Restrictions.and(Restrictions.eq("listPropertyValue" + ".clusterId", clusterId),
                        Restrictions.eq("listPropertValue" + ".companyWarehouseId", idCompanyWarehouse))));
        lstCriterios
                .createAlias("listProperty" + "." + "listPropertyValue", "listPropertyValue",
                        CriteriaSpecification.LEFT_JOIN,
                        Restrictions.eq("listPropertyValue" + ".clusterId", clusterId));
    } else {
        lstCriterios.createAlias("listProperty" + ".listPropertyValue", "listPropertyValue",
                CriteriaSpecification.LEFT_JOIN);
    }

    lstCriterios.add(Restrictions.eq(ID_CATEGORY, idCategory));
    lstCriterios.add(Restrictions.eq("listProperty" + ".groupId", idGroup));
    lstCriterios.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
    /*
     * Sorting
     */
    lstCriterios.addOrder(Order.asc("order"));
    lstCriterios.addOrder(Order.asc("listProperty" + ".order"));


    lstCriterios.addOrder(Order.asc("listPropertyValue"+ ".clusterId")); // Agrupacion, podría ser nulo
    lstCriterios.addOrder(Order.asc("listPropertyValue"+ ".propertyId")); // Propiedad
    lstCriterios.addOrder(Order.asc("listPropertyValue"+ ".id"));

    return lstCriterios.list();

组映射:

<list name="listProperty" 
        table="FICHA_PROPIEDAD" schema="${db2.siglo.schema}"
        inverse="false" cascade="all" >

        <key column="ID_FICHA_GRUPO" not-null="false" />
        <list-index column="ORDEN" base="1"/>

        <one-to-many
            class="com.company.aslo.appwebsiglo.model.card.property.property.CardProperty" />
</list>

属性映射:

<bag name="listPropertyValue" 
        table="FICHA_PROPIEDAD_VALOR" schema="${db2.siglo.schema}" 
        inverse="false" cascade="all">

        <key column="ID_FICHA_PROPIEDAD" not-null="false" />
        <one-to-many
            class="com.company.aslo.appwebsiglo.model.card.propertyvalue.propertyvalue.CardPropertyValue" />
</bag>

1 个答案:

答案 0 :(得分:0)

似乎我们的模型设计很糟糕,我们没有意识到如果数据库表FICHA_PROPIEDAD_VALOR具有复合键,我们不能只映射复合键中的一个属性,因为它会给我们带来意想不到的结果。

由于这个和嵌套对象,我们还有Hibernate使用的hashCode()和equals()方法的错误实现。

我之前使用ResultTransformer从SQLQuery获取行来解决了这个问题,但是在重构和更改模型设计之后我们得到了Hibernate解决方案。