繁体   English   中英

Hibernate 标准 API @ElementCollection 上的子查询

[英]Hibernate Criteria API Subquery on @ElementCollection

我已经搜索了很多,但无法让它工作。 我也发现了这个,它很接近,但它需要不必要的连接并且不能忽略大小写敏感: Criteria API not in @ElementCollection

这是简化的实体:

@Entity(name = "Users")
public class User {
    @Id
    @Column(columnDefinition = "TEXT")
    private String id;

    @ElementCollection
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<String> communities;
}

jpa/hibernate 魔法将其转换为两个表: users(text id)users_communities(text id, text community)

简单的 sql 语句我想 map 到一个标准是:

select u.id from users u
   where u.users_id not in (
    select uc.users_id
    from users_communities uc
    where lower(communities) = 'test_user_app'
);

这是我当前的 java 代码。 如何在 subJoin 上使用“criteriaBuilder.lower()”? 没有更简单的方法吗? 是不是可以避免手动subJoin?

Subquery<String> subquery = criteria.subquery(String.class);
Root<User> subRoot = subquery.from(User.class);
Join<Object, Object> subJoin = subRoot.join("communities");
subquery.select(subRoot.get("id"));
subquery.where(criteriaBuilder.equal(root.get("id"), subRoot.get("id")), subJoin.in("community_to_find"));
return criteriaBuilder.exists(subquery);

难以置信,花了我一整天的时间......如果不需要不区分大小写或类似的表达,最简单的方法是:

criteriaBuilder.isMember(
   "community_to_find", 
   criteria.from(User.class).get("communities")
); 

如果确实需要类似的表达式或不区分大小写:目前似乎无法避免不必要的子连接:无论如何,这最终使我的测试再次变绿:-):

Subquery<String> subquery = criteria.subquery(String.class);
Root<User> subRoot = subquery.from(User.class);
subquery.select(subRoot.get("id"));
subquery.where(criteriaBuilder.like(criteriaBuilder.lower(subRoot.join("communities")), argument));
return criteriaBuilder.in(root.get("id")).value(subquery);

         

提示:您可能已经从外部查询中定义了 Root,并且由于它是 ElementCollection,因此很可能是相同的 class。 在这种情况下,您可以通过以下方式定义更通用的 subRoot:

Root<? extends User> subRoot = subquery.from(root.getJavaType());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM