4

私は Hibernate (3.3.x) を使用しており、次の 2 つのエンティティがあります。

public class FtChargeAcctPkgDtl {
    private FtChargeAcctPkgDtlId id;
    private Set<FtChargeAcctPkgRate> ftChargeAcctPkgRates;
}

public class FtChargeAcctPkgRate {
    private FtChargeAcctPkgRateId id;
}

(簡単にするために、他の属性とセッターは省略しています)。

私はネイティブクエリを持っています:

<sql-query name="readSymbolsFtPackages">
    <return alias="pkgDtl" class="somepackage.FtChargeAcctPkgDtl"/>

    <return-join alias="pkgRate" property="pkgDtl.ftChargeAcctPkgRates"/>
    <![CDATA[
    SELECT {pkgDtl.*}, {pkgRate.*}

    FROM ft_charge_acct_pkg_dtl pkgDtl

    JOIN ft_charge_acct_pkg_rate pkgRate
      ON pkgRate.master_seq_no = pkgDtl.master_seq_no -- just primary key
        AND pkgRate.pkg_id = pkgDtl.pkg_id
]]>
</sql-query>

クエリは、FtChargeAcctPkgDtl#ftChargeAcctPkgRates が入力された状態で、pkgDtl のすべてのアイテムに対して 1 つの行を返すと想定されています (私はそれを望んでいます)。

メイン (pkgDtl) テーブルに 5 つの行があり、結合されたテーブルに 50 行あるとします (単一の pkgDtl に対して平均 10 pkgRates)。を使用してクエリを呼び出すと、

Query query = session.getNamedQuery("readSymbolsFtPackages");
query.list();

私は50行を取得します。ただし、そのうちの 45 は重複しています。これらの 5 つの pkgDtls と、それぞれに pkgRates が入力されたものを取得したいと考えています。休止状態でこれを行う方法はありますか?

4

2 に答える 2

3

使用する:

Query query = session.getNamedQuery("readSymbolsFtPackages");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
query.list();

よろしく

于 2012-08-22T14:28:08.313 に答える
2

@manu-navarro にインスパイアされて、このトランスフォーマーを使用しました。

/**
 * Transformer, that returns only distinct rows from the set.
 *
 * Distinction is based on all &lt;return alias/&gt; items.
 */
public class DistinctResultTransformer extends BasicTransformerAdapter {
    @Override
    public List transformList(List collection) {
        // set of objects already in the result
        Set<List<Object>> existingRows = new HashSet<List<Object>>();
        List result = new ArrayList();

        for (Object row : collection) {
            // array must be converted to list as array has equals() implemented using ==
            List<Object> rowAsList = Arrays.asList((Object[]) row);

            if (!existingRows.contains(rowAsList)) {
                existingRows.add(rowAsList);
                result.add(row);
            }
        }

        return result;
    }
}

そして、それを使用して登録しました

Query query = session.getNamedQuery("readSymbolsFtPackages");
query.setResultTransformer(new DistinctResultTransformer());
query.list();

これは非常にうまく機能します。

于 2012-08-23T08:24:06.677 に答える