鉴于以下实体:
@Entity
public class User {
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "user", fetch = LAZY)
private Set<UserRole> userRoles = new HashSet<>();
}
@Entity
public class UserRole {
@Id
private Long id;
private String name;
@ManyToOne(fetch = LAZY)
private User user;
@ManyToMany(fetch = LAZY)
private Set<Article> articles = new HashSet<>();
}
@Entity
public class Article {
@Id
private Long id;
private String name;
@ManyToMany(mappedBy = "articles", fetch = LAZY)
private Set<UserRole> userRoles = new HashSet<>();
}
我正构建以下查询:
From<?, ?> root = query.from(User.class);
From<?, ?> joinedUserRoles = (From<?, ?>) root.fetch("userRoles", JoinType.INNER);
From<?, ?> joinedArticles = joinedUserRoles.join("articles", JoinType.INNER);
query.where(joinedArticles.in(someArticles));
我们的想法是在简单加入User#userRoles
时获取加入UserRole#articles
。问题是生成的查询无效:
select
user0_.id as id1_6_0_,
userroles1_.id as id1_7_1_,
user0_.name as name5_6_0_,
userroles1_.role as role2_7_1_,
userroles1_.user_id as User_i3_7_1_,
userroles1_.user_id as User_i3_7_0__,
userroles1_.id as id1_7_0__
from
User user0_
inner join
UserRole userroles1_
on user0_.id=userroles1_.user_id
where
generatedAlias2 in (
?
)
抛出错误:
SQLSyntaxErrorException: Unknown column 'generatedAlias2' in 'where clause'
实际上,由于某种原因,JPA / Hibernate没有生成简单连接UserRole#articles
。
知道发生了什么?
我在使用Hibernate 5.2.16。
答案 0 :(得分:2)
根据Batch fetching - optimizing object graph loading:
JPQL不允许连接提取的别名,因此如果您还要查询关系,则必须连接两次。
为什么禁止这样做的一个例子是in this answer。
您的转换允许构建条件对象,但提供商似乎没有正确理解它并且无法解析articles
别名。
使用fetch()
替换join()
在加载延迟关系方面可能并不理想,但应构建有效的查询。
答案 1 :(得分:0)
再看一遍:这有什么问题?似乎工作。
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> user = cq.from(User.class);
Join<User, UserRole> userRoles = user.join("userRoles", JoinType.INNER);
Join<UserRole, Article> articles = userRoles.join("articles", JoinType.INNER);
cq.where(articles.in(Arrays.asList(new Long[]{1L})));