3

次の ManyToMany マッピングがあります。

@Entity
public class Class1 {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "class1_class2", joinColumns = @JoinColumn(name = "class1Id"),  inverseJoinColumns = @JoinColumn(name = "class2Id"))
private List<Class2> class2;
}

@Entity
public class Class2 {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
}

class2Id = 1 および class2Id =2 および class2Id =3 で、Classe2 エンティティと関係があるすべての Class1 エンティティを取得したいと考えています。{1,2,3}

または、class2 リストにある Classe1 エンティティをフィルタリングするには、次の値を持つ Class2 エンティティをフィルタリングします: class2Id = 1 および class2Id =2 および class2Id =3

例えば:

結合テーブルの場合、次の値を取得しています。

class1Id   class2Id
   1          1
   1          2
   1          3
   1          4
   6          1
   6          2
   6          3
   4          1
   5          2

この例の場合、結果は class1Id: 1 および 6 の Class1 になります。class1Id=1 の Class1 エンティティには classe2Id: 1,2,3, 4 との関係があり、class1Id=2 の Class1 エンティティには classe2Id: 1 との関係があるためです。 ,2,3

JPA2 (述語) で返される正しいエンティティを取得することは可能ですか?

そして、このケースを処理するためのより良いマッピングはありますか?

現時点では、次の SQL クエリを思いつきました。

select v1.class1Id from class1_class2 v1
inner join class1_class2 v2 on v1.class1Id=v2.class1Id
inner join class1_class2 v3 on v2.class1Id=v3.class1Id
where v1.classe2Id=1 and v2.classe2Id=2 and v3.classe2Id=3;
4

3 に答える 3

4

役立つクエリは次のとおりです。

select c1 
from Class1 c1 
join c1.class2 c2 
where c2.id in (1,2,3)
group by c1
having count(c1)=3 ;
于 2012-08-10T18:27:38.193 に答える
3

クラスClass2で最初に、以下を追加する必要があります。

@ManyToMany(fetch = FetchType.LAZY, mappedBy="class2")
private List<Class1> class1;

この後、タスクは次のクエリで実行する必要があります。

select c1 from Class1 c1 join c1.class2 c2 where c2.id in ?1 group by c1

List<Long>ここで、?1 - ID を含むタイプのオブジェクト{1,2,3}

于 2012-08-10T11:59:49.843 に答える
1

結合テーブルの値に class1Id=2 が表示されないか、class1Id=6 が class2Id=1 しかないため、まだいくつかの部分が明確ではありません。とにかく、必要に応じて変更できるように、同様の述語マッピングの例を示します。StaticMetaModelsを使用しました。それらをエンティティ クラスの同じパッケージに移動できます。もちろんテストはできませんでしたが、良いロードマップになると思います。

JPA 2.0 クエリ:

     CriteriaBuilder criteriaBuilder = getEm().getCriteriaBuilder();

     CriteriaQuery<Class1> criteriaQuery = criteriaBuilder.createQuery(Class1.class);

     Root<Class1> fromClass1 = criteriaQuery.from(Class1.class);

     List<Predicate> conditions = new ArrayList<Predicate>();

     Subquery<Class2> qry = criteriaQuery.subquery(Class2.class);                     

     Root<Class2> fromClass2 = qry.from(Class2.class);

     qry.select(fromClass2);

     qry.where(criteriaBuilder.equal(fromClass2.get(Class2_.getId()), idParamGoesHere));

     conditions.add(criteriaBuilder.in(.get(Class1_.getClass2()).value(qry));

     criteriaQuery.where(conditions.toArray(new Predicate[0]));

     TypedQuery<Class1> query = getEm().createQuery(criteriaQuery);

     List<Class1> results = query.getResultList();

StaticMetaModel Class1: (この場合は必要ありませんが、追加しました)

@StaticMetamodel(Class1.class)
public class Class1_ {

    private static volatile SingularAttribute<Class1, Long> id;
    private static volatile SingularAttribute<Class1, Class2> class2;

public static SingularAttribute<Class1, Long> getId() {
        return id;
    }
    public static void setId(SingularAttribute<Class1, Long> id) {
        Class1_.id = id;
    }
    public static SingularAttribute<Class1, Class2> getClass2() {
        return class2;
    }
    public static void setClass2(SingularAttribute<Class1, Class2> class2) {
        Class1_.class2 = class2;
    }
}

StaticMetaModel クラス 2:

@StaticMetamodel(Class2.class)
public class Class2_ {

    private static volatile SingularAttribute<Class2, Long> id;

public static SingularAttribute<Class2, Long> getId() {
        return id;
    }
    public static void setId(SingularAttribute<Class2, Long> id) {
        Class2_.id = id;
    }
}
于 2012-08-09T23:21:35.857 に答える