How can I get multiple objects with JPA?

I am using JPA2 / hibernate with this data model:

class Stock {
  @ManyToOne
  private StockGroup stockGroup;
  private boolean visible;
}
class StockGroup {
  @OneToMany(mappedBy = "stockGroup")
  private List<Stock> stocks;
}

I would like to get a StockGroup containing Stock, where visible==true.
I came with this faulty code:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<StockGroup> q = cb.createQuery(StockGroup.class);
Root<StockGroup> r = q.from(StockGroup.class);
Join<StockGroup, Stock> j = r.join(StockGroup_.stocks, JoinType.INNER);
Predicate p = cb.equal(j.get(Stock_.visible), true);

// This becomes a cartesian product :(
List<StockGroup> l = em.createQuery(q.where(p)).getResultList();   
// Stocks are not filtered on visible :(
l.get(0).getStocks();

Is it possible to get StockGroup and Stock Objects using the same CriteriaQuery or can JPA populate only one type at a time? Or can I add some criteria when .getStocks()filling up lazily?

+5
source share
1 answer

The trick with this is to return a tuple containing the old-fashioned connection between the Foundation and StockGroup, for example:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = cb.createQuery(Tuple.class);
Root<Stock> sRoot = q.from(Stock.class);
Root<StockGroup> sgRoot = q.from(StockGroup.class);

q.select(cb.tuple(sRoot, sgRoot)).where(
    cb.and(cb.equal(sRoot.get(Stock_.stockGroup), sgRoot),
        cb.isTrue(sRoot.get(Stock_.visible))));
List<Tuple> l = em.createQuery(q).getResultList();

, ( , ):

for (Tuple t : l) {
    Stock s = (Stock) t.get(0);
    StockGroup sg = (StockGroup) t.get(1);

    System.out.println("Stock is : " + s + "    .... StockGroup: " + sg);
}

IBM DeveloperWorks JPA2.

JPA2!

+8

All Articles