JPA criteriabuilder“IN”谓词外键错误:对象比较只能使用equal()或notEqual()运算符

时间:2011-04-18 14:02:38

标签: jpa criteria predicate

我想通过查看哪些用户有权检索该文件来从表中选择文件引用列表。为此,我有3个表,一个文件表,一个访问控制表和一个用户表。

我正在使用JPA和Criteriabuilder(因为涉及更多的表,我需要dynamicle创建查询,为了便于阅读,我将其他表和谓词从这个问题中删除)。

以下代码可以使用

CriteriaBuilder queryBuilder = em.getCriteriaBuilder();                         
CriteriaQuery<File> queryDefinition = queryBuilder.createQuery(File.class);   
Root<File> FileRoot = queryDefinition.from(File.class);                      
List<Predicate> predicateList = new ArrayList<Predicate>();    

Predicate userPredicate = FileRoot .join("FileAccesControlCollection").join("userId").get("usersId").in(loggedInUser.getUsersId());

predicateList.add(userPredicate );               

queryDefinition.where(predicateArray).distinct(true);                      
Query q = em.createQuery(queryDefinition);
List<Files> results = (List<Files>) q.getResultList(); 

对于userpredicate,我想省去最后一次加入users表,因为我想要过滤的ID已存在于FileAccesControlCollection表中,而join是一个计算成本高昂的数据库操作。

我尝试的是这样做:

Predicate userPredicate = FileRoot .join("FileAccesControlCollection").get("usersId").in(loggedInUser.getUsersId());

但我想因为FileAccesControlCollection实体类中的userId值是对Users类的外键引用,我得到以下错误:

Exception Description: Object comparisons can only use the equal() or notEqual() operators.  Other comparisons must be done through query keys or direct attribute level comparisons. 

有没有办法,使用loggedInUser实体或其Id,通过将File类加入FileAccesControlCollection类并过滤userId外键来过滤文件?我对JPA很新,并且使用谷歌引导我进入很多页面,但对于我认为应该可行的事情,我的回答并不清楚。

2 个答案:

答案 0 :(得分:2)

所以“userId”被映射为OneToOne?然后就可以了,

get("userId").get("id").in(...)

您还可以在EclipseLink中使用DescriptorCustomizer为外键字段添加QueryKey,然后在查询中使用它,

get("userFk").in(...)

答案 1 :(得分:0)

试试这个:

Predicate userPredicate = FileRoot.join(FileAccesControlCollection.class).join(Users.class).get("{id field name in class Users}").in(loggedInUser.getUsersId());
祝你好运。