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

发布于 2024-11-02 11:49:31 字数 1615 浏览 2 评论 0原文

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

我正在使用 JPA 和 Criteriabuilder (因为涉及更多表,并且我需要动态创建查询,为了可读性,我省略了这个问题中的其他表和谓词)。

以下代码有效

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 表中,并且联接是一项计算成本较高的数据库操作。

我尝试的是这样做:

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. 

有没有一种方法,使用loggingInUser实体或其Id来过滤只需将 File 类加入到 FileAccesControlCollection 类并根据 userId 外键进行过滤即可获取文件?我对 JPA 有点陌生,使用 google 引导我访问了很多页面,但对于在我看来应该是可能的事情没有明确的答案。

I want to select a list of file references from a table by looking at which users have the rights to retrieve that file. To do this I have 3 tables, a file table, an access control table, and a users table.

I am using JPA and Criteriabuilder (because there are more tables involved and I need dynamicle create the query, I am leaving out the other tables and predicates from this question for the sake of readability).

The following code works

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(); 

For the userpredicate I want to leave out the last join to the users table because the ID that I want to filter on is already present in the FileAccesControlCollection table, and a join is a computational expensive database operation.

What I tried is to do this:

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

But I guess because the userId value in the FileAccesControlCollection entity class is a foreignkey reference to the Users class I get the following error:

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. 

Is there a way, using the loggedInUser entity or its Id, to filter the files by just joining the File class to the FileAccesControlCollection class and filtering on the userId foreign key? I am kind of new to JPA and using google lead me to a lot of pages but not a clear answer for something which seems to me should be possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小忆控 2024-11-09 11:49:31

那么“userId”被映射为OneToOne?然后你可以这样做,

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

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

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

So "userId" is mapped as a OneToOne? Then you could do,

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

You could also add a QueryKey in EclipseLink using a DescriptorCustomizer for the foreign key field and then use it in the query,

get("userFk").in(...)
把时间冻结 2024-11-09 11:49:31

试试这个:

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

祝你好运。

try this:

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

good luck.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文