如何在JPQL中获取相关集合的第一个成员

时间:2011-09-02 17:04:36

标签: jpa-2.0 java-ee-6 jpql

我有Product表,其中有一个相关表格图像的关系为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 Entity,因此在查询中我可以调用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 个答案:

答案 0 :(得分:2)

首先,您无法从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