1

必要な休止状態のクエリを作成するのを手伝ってくれる人はいますか?

AreasAreasLocalの 2 つのテーブルがあります。1 つ目はアプリのメニューを含むツリー テーブルとして構造化され、2 つ目はエリア名の i18n リポジトリとして機能します。

選択した言語 (idLocal 属性) に従って、エリア全体のメニュー ツリーを可能な限り最適化したいと考えています (熱心に、できるだけ少ないクエリで)。

次のクエリでは、ローカライズされた名前が混在して表示されることを除いて、エリア ツリー メニューを正しく描画します(スペイン語のエリア名と英語のエリア名など)。

Query query = this.sessionFactory.getCurrentSession().createQuery(
    "select distinct areas" +
    " from Areas areas" +                       
    " left join fetch areas.children childs " +
    " left join fetch areas.locales locales" +
    " where areas.visible = 1 and areas.parent.idArea = :idArea" +  
    " and areasLocal.id.idLocal = :idLocal " +
    " order by areas.orden ");

query.setParameter("idArea", idArea);
query.setParameter("idLocal", idLocal); 




public class Areas implements Serializable {

    private Integer idArea;
    private Areas parent;
    private Integer idTipoAreas;
    private Boolean visible;
    private Integer orden;
    private Set<Areas> children = new HashSet<Areas>(0);
    private Set<AreasLocal> locales = new HashSet<AreasLocal>(0);

    //setters getters ommited       
}

public class AreasLocal implements Serializable {

    private AreasLocalId id;
    private String name;

    //setters getters ommited       
}



public class AreasLocalId implements Serializable {

    private int idArea;
    private int idLocal;

    //setters getters ommited       

}

<hibernate-mapping>
    <class name="Areas" table="areas">
        <id name="idArea" type="java.lang.Integer">
            <column name="ID_AREA" />
        </id>
        <many-to-one name="parent" class="Areas" fetch="select">
            <column name="ID_PARENT"/>
        </many-to-one>
        <property name="idTipoAreas" type="java.lang.Integer">
            <column name="ID_TIPO_AREAS" not-null="true" />
        </property>
        <property name="visible" type="java.lang.Boolean">
            <column name="ES_VISIBLE" not-null="true" sql-type="bit" />
        </property>
        <property name="orden" type="java.lang.Integer">
            <column name="ORDEN" />
        </property>
        <set name="children" table="areas" inverse="true" lazy="false" fetch="select" order-by="ID_AREA">
            <key>
                <column name="ID_PARENT"/>
            </key>
            <one-to-many class="Areas" />
        </set>                
        <set name="locales" table="areas_local" inverse="true" lazy="false" fetch="select">
            <key>
                <column name="ID_AREA"/>
            </key>
            <one-to-many class="AreasLocal" />
        </set>
    </class>
</hibernate-mapping>


<hibernate-mapping>
    <class name="AreasLocal" table="areas_local">
        <composite-id name="id" class="AreasLocalId">
            <key-property name="idArea" type="java.lang.Integer">
                <column name="ID_AREA" />
            </key-property>
            <key-property name="idLocal" type="java.lang.Integer">
                <column name="ID_LOCAL" />
            </key-property>
        </composite-id>
        <property name="name" type="string">
            <column name="NAME" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

HQL では再帰結合が許可されていないことに気付きました。

したがって、次のようなことを行う必要があります: しかし、期待どおりに動作せず、子を持つより深いメニューのみが取得されます。

Query query = this.sessionFactory.getCurrentSession().createQuery(
    "select distinct areas0" +
    " from Areas areas0" +      

    " left join fetch areas0.children areas1" +
    " left join fetch areas0.locales areas0Locales" +

    " left join fetch areas1.children areas2" +
    " left join fetch areas1.locales areas1Locales" +               

    " left join fetch areas2.children areas3" +
    " left join fetch areas2.locales areas2Locales" +               

    " left join fetch areas3.children areas4" +
    " left join fetch areas3.locales areas3Locales" +               

    //"..." +

    " where areas0.esVisible = 1" +
    " and areas0.parent.idArea = :idArea" +

    " and areas0Locales.id.idLocal = :idLocal " +       
    " and areas1Locales.id.idLocal = :idLocal " +           
    " and areas2Locales.id.idLocal = :idLocal " +           
    " and areas3Locales.id.idLocal = :idLocal " +           

    //"..." +

    " order by areas0.orden ");

どんな助けでも感謝されます

4

0 に答える 0