我有两个类,Account
并且Admin
,具有多对多映射。该类Admin
有一个类的集合,Account
反之亦然。
我想写一个查询,给定帐户 ID,将返回所有帐户管理员。
这是Account
该类的相关字段:
@Entity
public class Account {
@Id
public Long id;
@ManyToMany(mappedBy = "account", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
public List<Admin> users = new ArrayList<>();
}
我已经尝试过定期查询Admin.class
with,multiselect
因为每个帐户都有一组管理员,但试图从中得到一个消息“org.hibernate.hql.internal.ast.QuerySyntaxException:无法找到适当的构造函数类 [models.Admin]。预期的参数是:java.util.Collection [select new models.Admin(generatedAlias0.users) from models.Account as generatedAlias0 where generatedAlias0.id=1L]"(这里可能是 1L,因为我调用了这个函数1 作为 accountId),由消息“无法在类 [models.Admin] 上找到适当的构造函数。预期的参数是:java.util.Collection”引起。TypedQuery<Admin>
CriteriaQuery<Admin>
IllegalArgumentException
QuerySyntaxException
代码:
private static List<Admin> readAccountAdmins(Long accountId) {
CriteriaBuilder cb = JPA.em().getCriteriaBuilder();
CriteriaQuery<Admin> cq = cb.createQuery(Admin.class);
Root<Account> root = cq.from(Account.class);
Predicate idPredicate = cb.equal(root.get(Account_.id), accountId);
cq.multiselect(root.get(Account_.users)).where(idPredicate);
TypedQuery<Admin> typedQuery = JPA.em().createQuery(cq); // exception thrown here
return typedQuery.getResultList();
}
之后我尝试运行 a TypedQuery<List<Admin>>
,因为我正在尝试阅读列表。这是尝试查询列表的第一次迭代:
private static List<Admin> readAccountAdmins(Long accountId) {
CriteriaBuilder cb = JPA.em().getCriteriaBuilder();
CriteriaQuery<List<Admin>> cq = cb.createQuery((Class<List<Admin>>)(Class<?>)(Collection.class));
Root<Account> root = cq.from(Account.class);
Predicate idPredicate = cb.equal(root.get(Account_.id), accountId);
cq.select(root.get(Account_.users)).where(idPredicate);
TypedQuery<List<Admin>> typedQuery = JPA.em().createQuery(cq);
return typedQuery.getSingleResult(); // exception thrown here
}
我使用getSingleResult
asgetResultList
导致编译错误,说实际返回值List<List<Admin>>>
与签名不匹配。
此方法引发了一个不同的异常,NonUniqueResultException
带有消息:“结果返回多个元素”。
在调试时,我尝试评估表达式typedQuery.getResultList()
并看到它实际上返回List<Admin>
而不是List<List<Admin>>
,所以我得到了这个函数的最后一次迭代:
private static List<Admin> readAccountAdmins(Long accountId) {
CriteriaBuilder cb = JPA.em().getCriteriaBuilder();
CriteriaQuery<List<Admin>> cq = cb.createQuery((Class<List<Admin>>)(Class<?>)(Collection.class));
Root<Account> root = cq.from(Account.class);
Predicate idPredicate = cb.equal(root.get(Account_.id), accountId);
cq.select(root.get(Account_.users)).where(idPredicate);
TypedQuery<List<Admin>> typedQuery = JPA.em().createQuery(cq);
return (List) typedQuery.getResultList();
}
现在,这个功能有效,但我的问题是为什么?为什么编译器决定getResultList
返回与实际返回值不同的值?