2

次のようなJPAデータベースのセットアップがあります。

@Entity
public class Contact {

    @Id
    private Long id;
    @Column(length = 64)
    private String firstname;
    @Column(length = 64)
    private String surname;

    @OneToMany(mappedBy = "contact") 
    private List<Address> adresses = new ArrayList<Address>();
    @OneToMany(mappedBy = "contact") 
    private List<Telephone> telephones = new ArrayList<Telephone>();

}

@Entity
public class Address {

    @Id
    private Long id;
    @Column(length = 128)
    private String street;
    @Column(length = 16)
    private String plz;


    @ManyToOne 
    private Contact contact;

}

@Entity
public class Telephone {

    @Id
    private Long id;
    @Column(length = 32)
    private String number;


    @ManyToOne
    private Contact contact;

}

これで、検索フォームに対して次のクエリが作成されました。

em.createQuery("SELECT DISTINCT c FROM Contact c LEFT JOIN c.addresses a LEFT JOIN c.telephones t "
                        + "WHERE c.surnameLIKE '%"+var_surname+"%' "
                        + "AND c.firstname LIKE '%"+var_firstname+"%' "
                        + "AND a.street LIKE '%"+var_street+"%'"
                        + "AND t.nummer LIKE '%"+var_telephone+"%'"
                        ).getResultList();

私の質問は、3 つのテーブルすべてを 1 つの JPA クエリで結合して、名前、通り、番号などを検索するにはどうすればよいですか? すでに LEFT JOIN を試しましたが、たとえば Telephone テーブルが空の場合は結果が得られません (すべてのテーブルに適切なエントリがある場合は適切に機能します)。たとえば、連絡先に複数の電話番号がある場合でも、電話番号がなく、結果が 1 つしかない場合でも、連絡先の結果リストが必要です。

事前にご協力いただきありがとうございます。

4

4 に答える 4

0

以下のような「LEFTOUTERJOIN」を使ってみましたか?

           "SELECT DISTINCT c FROM Contact c LEFT OUTER JOIN c.addresses a LEFT OUTER JOIN c.telephones t "
          + "WHERE c.surnameLIKE '%"+var_surname+"%' "
          + "AND c.firstname LIKE '%"+var_firstname+"%' "
          + "AND a.street LIKE '%"+var_street+"%'"
          + "AND t.nummer LIKE '%"+var_telephone+"%'"
          ).getResultList();
于 2012-09-28T19:01:04.313 に答える
0

「LEFT OUTER JOIN a ON b」スタイルの構文は JPA ではサポートされていません ( http://chrisiecorner.blogspot.fi/2012/12/jpa-and-outer-joins.htmlを参照) 。

ネイティブ クエリを実行する必要があります。

于 2014-02-06T04:39:36.220 に答える
0

役立つ回答をありがとうございます。最後に、検索文字列を動的に構築して問題を解決し、ユーザーが空のままにしたフィールドに応じて、結合オペランドの一部を選択的に追加/削除する必要がありました。

    public List<Person> querySearch(String snachname, String svorname, String srechtsform, String sadresse, String sort, String sland, String stelefon, String semail, LoadGroup group) {
        if(srechtsform.equals("Alle")) {
            srechtsform = "";
        }
        if(sland.equals("Alle")) {
            sland = "";
        }
        String q = "SELECT DISTINCT * FROM Person p LEFT OUTER JOIN Adresse a ON (a.PERSON_ID=p.ID) LEFT OUTER JOIN Telefon t ON (t.PERSON_ID=p.ID) LEFT OUTER JOIN Email e ON (e.PERSON_ID=p.ID) WHERE p.nachname1 LIKE '%"+snachname+"%'AND p.vorname LIKE '%"+svorname+"%' AND p.rechtsform LIKE '%"+srechtsform+"%' ";
        if(sadresse.equals("") && sort.equals("") && sland.equals("")) {
            q += "AND (a.ID IS NULL OR (a.strasse LIKE '%"+sadresse+"%' AND a.ort LIKE '%"+sort+"%' AND a.land LIKE '%"+sland+"%')) "; 
        } else {
            q += "AND a.strasse LIKE '%"+sadresse+"%' AND a.ort LIKE '%"+sort+"%' AND a.land LIKE '%"+sland+"%' "; 
        }
        if(stelefon.equals("")) {
            q += "AND (t.ID IS NULL OR t.nummer LIKE '%"+stelefon+"%') ";
        } else {
            q += "AND t.nummer LIKE '%"+stelefon+"%' ";
        }
        if(semail.equals("")) {
            q += "AND (e.ID IS NULL OR e.mailadresse LIKE '%"+semail+"%') ";
        } else {
            q += "AND e.mailadresse LIKE '%"+semail+"%' ";
        }
        q += "GROUP BY p.ID";
        Query query = em.createNativeQuery(q, Person.class);
        if(group!=null) { query.setHint(QueryHints.LOAD_GROUP, group); }
        return query.getResultList();
    }
于 2012-10-24T08:08:13.310 に答える
0

DISTINCT は重複を削除する必要があります。

関係がない場合に結果を取得するには、OR を使用する必要があります。

      + "AND ((a.id is null) OR (a.street LIKE '%"+var_street+"%'))"
于 2012-10-01T13:24:24.070 に答える