7

最近、春のデータjpaで3つのテーブルを結合するのに苦労しています。Series、およびの 3 つのエンティティがDossierありItemます。Series多くDossiersの をDossier持ち、多くのItems(関係) を持っています。私は次のようなことSeries.join(Dossier_.series).join(Dossier_.items)を行い、結合セットになります。次のクエリを作成します。

Select Items from Series,Dossier,Item 
Where Series.Id=Dossier.seriesId 
and Dossier.id=Item.dossierId 
and series.projectId = :param

このステートメントをSpringの仕様と基準APIで表現することはできません....いくつかの光を当ててください

4

3 に答える 3

8

それはJPAの質問です。

まず、「テーブル」にアクセスしていないことを常に強調しています。それらをドメイン エンティティとして表示する必要があります。JPA/Hibernate/その他の ORM の多くの誤用は、実際には SQL またはデータベースの概念の直接的な「変換」に由来します。

質問に戻りますが、答えは簡単です。まず、ドメイン エンティティに実際に「関係」があることを確認します。ID の保存は、具体的なドメイン モデルの構築に役立たない。たとえば、次のようなものがあります。

@Entity
class Series {
  @Id
  Long id;

  @OneToMany(mappedBy="series")
  List<Dossier> dossiers;
}
@Entity
class Dossier{
  @Id
  Long id;

  @ManyToOne
  Series series;

  @OneToMany(mappedBy="dossier"
  List<Item> items;
}

@Entity
class Item{
  @Id
  Long id;

  @ManyToOne
  Dossier dossier;
}

クエリは簡単です。

select s.dossiers.items from Series s where s.projectId = :param

@ManyToOneまたは、s のみを使用してs を省略する方が合理的である場合@OneToManyでも、クエリは単純です。

from Item where i.dossier.series.projectId = :param
于 2013-01-29T00:50:25.357 に答える
0

[まだ難しい] 多分私は自分自身を明確にしていませんでした.私はHQLでクエリを表現する方法を知っています.問題は、クライテリアAPIの助けを借りて、Spring Dataの仕様を使用してそのクエリを構築することです.

//Let's exampine the following piece of code

        public class CustomItemSpecs {

        public static Specification<Item> createSpecificationFromSearchForm(final SearchForm searchForm) {  
            return new Specification<Item>() {
                @Override  
                public Predicate toPredicate(Root<Item> root, CriteriaQuery<?> query, CriteriaBuilder cb) {             
        CriteriaQuery<Item> cq = cb.createQuery(Item.class);


                    CriteriaQuery<Series> sb = cb.createQuery(Series.class);
                    Root<Series> series = sb.from(Series.class);

                    Join<Series,Dossier> join1 = series.join(Series_.dossiers);

                    Join<Dossier, Item> join2 = join1.join(Dossier_.items);
        }
}

    }

ご覧のとおり、2 つの別々の結合を行うことができます。問題は、上記のクエリを実行するために Series、Dossier、Items を結合したい場合です。join2 は Dossier-Item セットであることに注意してください。cb のような基準を作成できません。 equals(join2.get(Series_.projectId),)

于 2013-01-29T08:24:58.160 に答える