我在GAE上使用JPA,此查询返回包含1个元素的List。 这个元素是一个org.datanucleus.store.types.sco.backed.ArrayList(它最终包含我的结果),而我期待一个产品列表。我做错了什么? Thanx提前!
Query query = entityManager.createQuery
("select p.products from Place p where p.id = :Id" );
query.setParameter("Id",id);
List<Product> resultList = query.getResultList();
//for debugging purpose
assert (resultList.get(0) instanceof Product);
if (resultList.size() > 0)
{
//raise a cast exception here
Product p = resultList.get(0);
}
@Entity
public class Place {
private Collection<Product> products;
@OneToMany(cascade = CascadeType.ALL)
public Collection<Product> getProducts() {
return products;
}
public void setProducts(Collection<Product> products) {
this.products = products;
}
private String id;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
答案 0 :(得分:2)
当JPQL规范说选择项应该是
时,从JPQL查询中选择多值字段是非法的"single_valued_path_expression | scalar_expression | aggregate_expression |
identification_variable | OBJECT(identification_variable) | constructor_expression"
所以答案说这个查询是正确的是错误的。如果您想要一个地方的“产品”,那么您可以检索地方并且它有产品。
答案 1 :(得分:1)
我对DataNucleus不是很熟悉,所以还没有执行。但是使用JPA,查询应该可以正常工作。您可以尝试以下代码来构建查询,该查询根据指定的类返回结果。
entityManager.createQuery("SELECT p.products FROM Place p WHERE p.id = :Id", Product.class);
来自文档:
<T> TypedQuery<T> createQuery(java.lang.String qlString,
java.lang.Class<T> resultClass)
创建TypedQuery实例以执行Java Persistence 查询语言语句。查询的选择列表必须包含 只有一个项目,必须可以分配给指定的类型 resultClass参数。
Parameters:
qlString - a Java Persistence query string
resultClass - the type of the query result
修改: 您可以尝试以下代码。
Place place = entityManager.createQuery("SELECT p FROM Place p WHERE p.id = :Id", Place.class).getSingleResult();
List<Products> products = place.getProducts();
另外作为旁注,您使用的是JPA,但@Extension
似乎是JDO特定的注释。
答案 2 :(得分:0)
该类javadoc告诉它实现了java.util.List
,因此它是一个有效的返回类型。
请记住,规范说您将List
作为返回类型,而不是java.util.ArrayList
,因此任何实现List
的类都与其他任何类一样有效。
更新:
尝试:
SELECT pr FROM Place pl INNER JOIN pl.products pr WHERE pl.id = :Id