Java JPA和criteriabuilder中的distinct和order by关系
我有这三种豆子: User.javaJava JPA和criteriabuilder中的distinct和order by关系,java,jpa,Java,Jpa,我有这三种豆子: User.java @Entity @Table(name = "usuario") public class User implements Serializable { private static final long serialVersionUID = 1L; private Set<Role> roles = new HashSet<Role>(0); private String login; priva
@Entity
@Table(name = "usuario")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Set<Role> roles = new HashSet<Role>(0);
private String login;
private String password;
private Integer id;
private DestinationGroup destinationGroup;
....
// Getters and setters
我想获得所有没有“admin”角色的用户,按其destinationGroup的名称排序。所以我使用这个代码:
UserTest.java
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class);
Root<User> root = criteriaQuery.from(User.class);
Join<User, Role> path = root.join("roles", JoinType.LEFT);
Expression<Object> filter = path.get("name");
Predicate localPredicate = criteriaBuilder.notEqual(filter, "admin");
criteriaQuery.where(localPredicate);
Join<User, DestinationGroup> path2 = root.join("destinationGroup", JoinType.LEFT);
Expression<Object> sort = path2.get("name");
List<Order> orders = new ArrayList<Order>();
orders.add(criteriaBuilder.asc(sort));
criteriaQuery.orderBy(orders);
TypedQuery<User> query = entityManager.createQuery(criteriaQuery);
List<User> users = query.getResultList();
CriteriaBuilder-CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery CriteriaQuery=criteriaBuilder.createQuery(User.class);
Root=criteriaQuery.from(User.class);
Join path=root.Join(“角色”,JoinType.LEFT);
表达式过滤器=path.get(“名称”);
谓词localPredicate=criteriaBuilder.notEqual(过滤器,“admin”);
其中(localPredicate);
Join path2=root.Join(“destinationGroup”,JoinType.LEFT);
表达式sort=path2.get(“name”);
列表顺序=新的ArrayList();
add(criteriaBuilder.asc(sort));
criteriaQuery.orderBy(订单);
TypedQuery=entityManager.createQuery(criteriaQuery);
List users=query.getResultList();
但如果任何用户具有多个角色,则会返回重复的结果。因此,我在测试代码的第二行添加了:“.distinct(true)”,以仅检索每个用户的一个结果:
CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class).distinct(true);
CriteriaQuery-CriteriaQuery=criteriaBuilder.createQuery(User.class).distinct(true);
然后抛出一个异常:“对于SELECT DISTINCT,ORDER BY表达式必须出现在SELECT列表中”。我无法删除orderBy,我希望避免重复的结果。我怎样才能解决这个问题?我可以向distinct添加关系吗
我尝试了n,但使用JoinType.INNER,我也得到了重复的结果。Distinct通常可以解决您的问题是的。你在使用什么数据库?虽然我想我知道什么是可行的:尝试在sql语句中包含distinct,而不是使用该方法。还有另一种方法,但这将是一个严重的“糟糕编程”案例,我的意思是,您可以将一个过滤算法放在从bean.Thnx获得的arraylist上,作为您的响应,但我更喜欢只使用criteria api。无论如何,我了解到,这可以通过将第8行更改为:Join path2=(JoinDistinct通常可以解决您的问题是的。您使用的是什么数据库?虽然我想我知道什么可以工作:尝试在sql语句中包含distinct,而不是使用该方法。有另一种方法,但这将是一个严重的问题“糟糕的编程”,我的意思是,你可以将一个过滤算法放在从bean.Thnx获得的arraylist上,作为你的响应,但我更喜欢只使用criteria api。无论如何,我了解到,这可以通过将第8行更改为:Join path2=(Join)来实现
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class);
Root<User> root = criteriaQuery.from(User.class);
Join<User, Role> path = root.join("roles", JoinType.LEFT);
Expression<Object> filter = path.get("name");
Predicate localPredicate = criteriaBuilder.notEqual(filter, "admin");
criteriaQuery.where(localPredicate);
Join<User, DestinationGroup> path2 = root.join("destinationGroup", JoinType.LEFT);
Expression<Object> sort = path2.get("name");
List<Order> orders = new ArrayList<Order>();
orders.add(criteriaBuilder.asc(sort));
criteriaQuery.orderBy(orders);
TypedQuery<User> query = entityManager.createQuery(criteriaQuery);
List<User> users = query.getResultList();
CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class).distinct(true);