Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 如何使用多个ElementCollections进行搜索_Jpa_Criteria_Jpql_Embeddable - Fatal编程技术网

Jpa 如何使用多个ElementCollections进行搜索

Jpa 如何使用多个ElementCollections进行搜索,jpa,criteria,jpql,embeddable,Jpa,Criteria,Jpql,Embeddable,鉴于以下实体: @Entity @Table(name = "subscription") public class Subscription implements Serializable { private static final long serialVersionUID = 1L; @ElementCollection @CollectionTable(joinColumns= @JoinColumn(name="subscription")) private Se

鉴于以下实体:

@Entity
@Table(name = "subscription")
public class Subscription implements Serializable {

  private static final long serialVersionUID = 1L;

  @ElementCollection
  @CollectionTable(joinColumns= @JoinColumn(name="subscription"))
  private Set<Code> mainCodes = new HashSet<>();

  @ElementCollection
  @CollectionTable(joinColumns= @JoinColumn(name="subscription"))
  private Set<Code> otherCodes = new HashSet<>();

}
在CriteriaBuilder中这样做是可行的,还是需要使用更明确的查询?如果是,查询是什么样子的

编辑:尝试使用CriteriaBuilder执行此操作:

final CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
final CriteriaQuery<Subscription> cq = cb.createQuery(Subscription.class);
final Root<Subscription> root = cq.from(Subscription.class);

final Expression<Collection<Code>> mainCodes = root.get("mainCodes");
final Predicate containsMainCode = cb.isMember(obj.getClassCode(), mainCodes);

final Expression<Collection<Code>> otherCodes = root.get("otherCodes");
final Predicate containsOtherCode = cb.isMember(obj.getOtherCode(), otherCodes);

final Predicate searchPredicate = cb.or(containsMainCode, containsOtherCode);
cq.select(root).where(searchPredicate);
但是,这会创建涉及的两个集合的内部联接,这意味着如果数据库中存在mainCode行,而不是otherCode行,则不会返回任何结果,它将生成以下查询:

选择t0.ID 来自订阅其他代码t2、订阅主代码t1、订阅t0 其中t1.CODESYSTEM=?和t1.CODE=?或者t2.CODESYSTEM=?和t2.CODE=?t1.subscription=t0.ID和t2.subscription=t0.ID


因此,即使它找到了匹配的主代码,如果没有任何其他代码,它也会失败。

在您的示例中,情况正好相反。 例如,如果代码具有name属性:

select s from Subscription s left join s.mainCodes m left join s.otherCodes o 
where m.name IN :myMainCode or o.name IN :myOtherCode

您的查询有什么问题?请使用编辑中的左关节。我没有使用标准,但有同等的建设。
select s from Subscription s left join s.mainCodes m left join s.otherCodes o 
where m.name IN :myMainCode or o.name IN :myOtherCode