Как получить первого члена связанной коллекции в JPQL - PullRequest
2 голосов
/ 02 сентября 2011

У меня есть таблица продуктов, у которой есть связанная таблица. Изображения с отношением 1: M.

Class Product {
  private Integer productId;
  private String productName;
  ....
  ....
  ....
  private List<Image> productImageList;
  ....
  ....
  ....
}

Class Image{
  private Integer imageId;
  private String imageName;
}

Class ProductLite{
  private Integer productId;
  private String productName;
  private String imageName;
}

Я пытаюсь выполнить запрос JPQL, в котором хочу запросить продукты и первое изображение из productImageList и вернуть объект ProductLite с использованием нового конструктора.

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public List<ProductLite> getAllProductLite() {
  Query q = em.createQuery("SELECT NEW com.mycomp.application.entity.ProductLite(p.productId, p.productName, p.productImageList.get(0).getImageName())"
                + " from Product p"
                + " ORDER by p.productName");
  List<ProductLite> prods = q.getResultList();
return prods;
}

Но по какой-то причине я не могу заставить его работать. Я получаю NoViableException. Поэтому я попытался переместить логику получения первого изображения (метод getImage ()) в объект Product, чтобы в запросе я мог просто вызвать getImage (). Даже это не похоже на работу.

java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Syntax error parsing the query [SELECT NEW com.meera.application.entity.ProductLite(distinct p.productId,  p.productName, p.getImage()) from Product p, IN(p.productImageList) pil  where p.category.categoryCode = :categoryCode   ORDER by p.productName ], line 1, column 52: unexpected token [distinct].
Internal Exception: NoViableAltException(23@[452:1: constructorItem returns [Object node] : (n= scalarExpression | n= aggregateExpression );])

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 02 октября 2011

Во-первых, вы не можете вызывать методы в классе сущности из вашего запроса JP QL. Во-вторых, чтобы использовать порядок объектов в списке, вам нужен постоянный порядок.

Чтобы создать столбец для заказа в таблице соединения между изображением и продуктом, необходимо добавить @ OrderColumn - аннотация к productImageList . Например:

@OrderColumn(name = "myimage_order")
//or dont't define name and let it default to productImageList_order
@OneToMany
private List<Image> productImageList;

Затем необходимо изменить запрос, чтобы использовать этот порядок, чтобы выбрать только первое изображение:

SELECT NEW com.mycomp.application.entity.ProductLite(
           p.productId, p.productName, pil.imageName)
FROM Product p JOIN p.productImageList pil
WHERE INDEX(pil) = 0
ORDER by p.productName
...