Как я могу получить несколько объектов с помощью JPA? - PullRequest
7 голосов
/ 11 января 2011

Я использую JPA2 / hibernate с этой моделью данных:

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

Я хотел бы получить StockGroup, содержащий Stock, где visible==true.
Я пришел с этим неисправным кодом:

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();

Возможно ли получить StockGroup и Stock Objects одним CriteriaQuery или JPA может заполнить только один тип за один раз? Или я могу добавить некоторые критерии, когда .getStocks() заполнен лениво?

1 Ответ

9 голосов
/ 12 января 2011

Хитрость для этого заключается в возврате кортежа, содержащего старомодное соединение между Stock и StockGroup, например:

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 Typesafe Queries

Удачи в ваших начинаниях JPA2!

...