【发布时间】:2020-05-11 12:15:46
【问题描述】:
所需的实体大致如下:
@Entity
@Table(name = "tb_users")
public class User {
@Id
@GeneratedValue
private UUID userId;
// Omitted other fields and getters/setters ...
}
@Entity
@Table(name = "tb_groups")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer groupId;
// ....
}
@Entity
@Table(name = "tb_group_members")
public class GroupMember {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "group_id")
private Group group;
// getters & setters ...
}
这是与中间表的多对多关系:
组 GroupMember 用户
我要实现的查询(通过Criteria API)与下面的JPQL基本相同:
select g from Group g join GroupMember gm on g = gm.group where gm.user = ? and ...or whatever...
我尝试按如下方式构造 CriteriaQuery:
User userToQuery = ...;
// ....
CriteriaQuery<Group> query = criteriaBuilder.createQuery(Group.class);
Root<Group> groupRoot = query.from(Group.class);
Root<GroupMember> gmRoot = query.from(GroupMember.class);
groupRoot.join(...).on(criteriaBuilder.equal(groupRoot, gmRoot.get("group"))); // I can't find a suitable join() method to specify the relationship
Predicate predicate = criteriaBuilder.equal(gmRoot.get("user"), userToQuery);
// ......
由于Group实体没有关联关系,所以不知道怎么调用join(...)方法。
我必须反向声明关联,即从 GroupMember 实体:
CriteriaQuery<GroupMember> query = criteriaBuilder.createQuery(GroupMember.class);
Root<GroupMember> gmRoot = query.from(GroupMember.class);
gmRoot.join("group");
// ......
JPA 的 Criteria API 有这个限制吗?
不包含关联字段join的实体如何与其他实体?
【问题讨论】:
-
您的 JPQL 有效吗?你试过像
SELECT gm.group FROM GroupMember gm WHERE gm.user=:user这样的JPQL吗?我认为,如果它确实有效,则更容易转换为标准 API。 -
这能回答你的问题吗? JPA - left join 2 tables without association
-
非常感谢~ Jens & Nikos!答案直接使用 JPQL,我已经给出了我的 JPQL,它工作正常。我希望使用Creteria API来解决这个问题,因为这样可以解决concat查询参数的问题
-
我已经放弃使用 Creteria API。我将尝试使用 Querydsl 进行更灵活的查询。
标签: jpa spring-data-jpa criteria-api