【问题标题】:Hibernate retrieves many-to-one without askingHibernate 无需询问即可检索多对一
【发布时间】:2014-02-24 18:33:44
【问题描述】:

我们的开发团队有一个大问题。

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

(映射在前面)

我们有两个主要问题:

A) 在进行 HQL 查询、条件查询或 SQLQuery 时,JOIN 或 WHERE 子句中应用的条件无关紧要,Hibernate 总是为我们检索所有底层对象。例如,如果我让 Criteria 或 SQL 只获取 Group 对象,Hibernate 就会出现并且(无论是否懒惰)也会获取所有 Property 和 Value 实例。我们想控制这一点。我们想做左连接,只获取内部没有值的属性(Hibernate 删除这些没有值的属性)

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

我们可以在休眠配置、获取模式/策略、映射配置或任何地方做些什么吗?我现在正在考虑使用 Result 转换器。

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

提前致谢

查询:

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>

【问题讨论】:

  • 您可以发布您正在尝试的条件/HQL 查询吗?
  • 你有没有试过用lazy=true上list?
  • 是的,我做到了。它不会改变任何东西

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


【解决方案1】:

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

由于这个和嵌套的对象,我们对 Hibernate 使用的 hashCode() 和 equals() 方法的实现也很糟糕。

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

【讨论】:

    猜你喜欢
    • 2018-06-22
    • 1970-01-01
    • 2013-07-13
    • 1970-01-01
    • 2013-03-29
    • 2021-07-08
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多