【问题标题】:@ManyToMany JPA 2 complex query@ManyToMany JPA 2 复杂查询
【发布时间】:2012-08-07 04:52:43
【问题描述】:

我有以下多对多映射。

@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;
}

我想检索与 Classe2 实体有关系的所有 Class1 实体,其中 class2Id = 1 和 class2Id =2 和 class2Id =3。 {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

对于本示例,结果将是 Class1 和 class1Id:1 和 6。 因为 Class1 实体,class1Id=1 与 classe2Id 有关系:1,2,3,4 而 Class1 实体,class1Id=2 与 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;

【问题讨论】:

  • 你能澄清你的问题/例子吗?
  • 我已经添加了更多说明

标签: java hibernate jpa jpa-2.0 spring-data-jpa


【解决方案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 Class2:

@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;
    }
}

【讨论】:

  • 您好,对于 class1Id=2,不需要。并且 class1Id=6 有 class2Id = 1 和 2 和 3。
  • 您的解决方案不起作用,因为 in 子句返回带有 class1Id = 4 和 5 的条目
  • 我已经更新了这个字段 conditions.add(criteriaBuilder.in(.get(Class1_.getClass2()).value(qry));
【解决方案2】:

首先在您的班级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

其中 ?1 - List&lt;Long&gt; 类型的对象,包含 ID {1,2,3}

【讨论】:

  • 为什么要添加与 class2 的关系?它的单向关系。您的查询不完整。我正在发布答案!
  • 实际上,您并没有在任何地方指定您的查询应该是单向的。无论如何,这个查询也适用于单向映射。
【解决方案3】:

以下是可以提供帮助的查询:

select c1 
from Class1 c1 
join c1.class2 c2 
where c2.id in (1,2,3)
group by c1
having count(c1)=3 ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 2016-01-22
    • 1970-01-01
    • 2016-08-17
    • 2011-12-26
    • 2014-12-27
    相关资源
    最近更新 更多