【问题标题】:JPA criteriaquery tuple onetomany joinJPA 标准查询元组单机连接
【发布时间】:2013-01-07 02:14:53
【问题描述】:

我需要与标准生成器进行连接,然后得到Tuple(Object[]) 类型的结果。第一个元组元素应该是Preke(并且可以正常工作),第二个Tuple 元素应该是一个包含@OneToMany 对象的List<PrekeTiekejas>。以下代码而不是 List<PrekeTiekejas> 返回单个 PrekeTiekejas 对象。我做错了什么?

CriteriaBuilder cb = MinutisManager.getInstance().getCriteriaBuilder();
CriteriaQuery<Tuple> criteriaQuery = cb.createTupleQuery();
Root<minutis.Preke> from = criteriaQuery.from(minutis.Preke.class);
ListJoin<minutis.Preke, minutis.PrekeTiekejas> tiekejai = from.joinList(Preke_.tiekejai.getName());
criteriaQuery.multiselect(from, tiekejai);

TypedQuery<Tuple> typedQuery = MinutisManager.getInstance().createQuery(criteriaQuery);
//pages
typedQuery.setFirstResult(0);
typedQuery.setMaxResults(100);
//typedQuery.setHint(QueryHints.REFRESH, HintValues.TRUE);

List<Tuple> tuples = typedQuery.getResultList();
for(Tuple t : tuples) {
   minutis.Preke preke = t.get(0, minutis.Preke.class);
   System.out.println(preke.getPavadinimas());
   List<minutis.PrekeTiekejas> tiek = t.get(1, List.class);
   System.out.println(tiek.size());
}

这是我得到的错误:

Testcase: testGetPrekesByFilters(database.dao.PrekeDAOTest):    Caused an ERROR
Element 1 type interface java.util.List is invalid for result "***PrekeTiekejas.toString()***".
java.lang.IllegalArgumentException: Element 1 type interface java.util.List is invalid  for result "***PrekeTiekejas.toString()***".
    at org.eclipse.persistence.internal.jpa.querydef.TupleImpl.get(TupleImpl.java:89)
    at database.dao.PrekeDAOTest.testGetPrekesByFilters(PrekeDAOTest.java:69)

PrekeDAOTest.java:69线:

List<minutis.PrekeTiekejas> tiek = t.get(1, List.class);

【问题讨论】:

    标签: eclipselink criteria-api multi-select


    【解决方案1】:

    JPA 不支持按您的预期返回集合,而是为每个 Preke PrekeTiekejas 对返回一个元组。您将需要自己处理结果并构建列表列表,或者更改您的期望。

    由于您正在查询已经具有到 PrekeTiekejas 的集合映射的 Preke 实体,您可以只返回 Preke 并在集合的每个实体上调用 getPrekeTiekejas()。使用 root.fetch(Preke_.tiekejai.getName(), JoinType.LEFT) 代替查询中的 joinList 以确保在查询中获取相关实体。比如:

    CriteriaQuery<minutis.Preke> criteriaQuery = cb.createQuery(minutis.Preke.class);
    Root<minutis.Preke> from = criteriaQuery.from(minutis.Preke.class);
    from.fetch(Preke_.tiekejai.getName(), JoinType.LEFT);
    criteriaQuery.select(from);//not really needed
    
    TypedQuery<minutis.Preke> typedQuery = MinutisManager.getInstance().createQuery(criteriaQuery);
    //pages
    typedQuery.setFirstResult(0);
    typedQuery.setMaxResults(100);
    //typedQuery.setHint(QueryHints.REFRESH, HintValues.TRUE);
    
    List<minutis.Preke> prekeList= typedQuery.getResultList();
    for(minutis.Preke p : prekeList) {
       System.out.println(preke.getPavadinimas());
       List<minutis.PrekeTiekejas> tiek = preke.getTiekejai();//assumes tiekejai has a getTiekejai accessor
       System.out.println(tiek.size());
    }
    

    【讨论】:

      猜你喜欢
      • 2016-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-19
      • 2017-03-13
      • 1970-01-01
      相关资源
      最近更新 更多