1

それらが私の実体であるとしましょう:

Table1.java

@Entity
public class Table1 {

    // Many to one
    private Table2 table2;

    // Raw attributes
    // ...

}

Table2.java

@Entity
public class Table2 {

    // Many to one
    private Table3 table3;

    // Raw attributes
    // ...

}

Table3.java

@Entity
public class Table3 {

    // Raw attributes
    private String lang; // "fr", "en", "de"...

}

Table1プロパティがにtable2.table3.lang等しいすべての行を一覧表示する場合は、次のenようにします。

Query query = entityManager.createQuery("SELECT t1 FROM Table1 t1 WHERE t1.table2.table3.lang = :lang");
query.setParameter("lang", "en");

そうは言っても、以前に入力されたクエリでそのクエリを実行するにはどうすればよいIterable<Table1>ですか?それは実行可能ですか?Hibernateを使用しない場合は、何を使用しますか?たとえば、以下のコードが機能しないことがわかっている場合でも、次のようになります。

Set<Table1> set = new HashSet<Table1>();
set.add(new Table1(INIT_DEFAULT_VALUES));
set.add(new Table2(INIT_DEFAULT_VALUES));
set.add(new Table3(INIT_DEFAULT_VALUES));

Query query = entityManager.createQuery("SELECT t1 FROM :set t1 WHERE t1.table2.table3.lang = :lang");
query.setParameter("set", set);
query.setParameter("lang", "en");

なぜそのようなものが必要なのか疑問に思っている人のために、私はApache LuceneTable1を使用して、以前はLuceneによってインデックス付けされていた行内のユーザーの検索を実行しています。いくつかの結果が得られたら、返されたリストにいくつかのフィルター/並べ替えを提案する必要があります。たとえば、リンクされたTable3エンティティの言語を選択します。

任意の提案をいただければ幸いです:)

4

1 に答える 1

1

HibernateクエリはSQLクエリに変換され、データベースで実行されます。セットにデータベースにないエンティティインスタンスが含まれている場合、Hibernateがそれらをクエリする方法はありません。

ご指摘のとおり、これらのエンティティが実際にデータベースのエンティティである場合は、次のIN句を使用できます。

Set<Long> ids = createSetOfIdsFromEntities(set);
String hql = select t1 FROM Table1 t1 WHERE t1. id in (:ids) and t1.table2.table3.lang = :lang";
...

ただし、IDが多すぎないこと、およびデータベースによって課せられた制限に達していないことを確認してください(たとえば、OracleはIN句の要素を1000に制限しています)。

それらのエンティティがすでにメモリにロードされている場合は、それらを反復処理することもできます。

Set<Table1> found = new HashSet<Table1>();
for (Table1 t1 : set) {
    if (t1.getTable2().getTable3().getLang().equals(theLang)) {
        found.add(t1);
    }
}
于 2012-06-06T10:19:01.950 に答える