问题
I am implementing a user management system which has the following entities :
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
Long id;
@Column(unique = true, name = "EMAIL")
private String email;
@Column(name = "NAME")
private String name;
@Column(name = "PASSWORD")
private String password;
@Column(name = "MOBILE")
private String mobile;
@Column(name = "OWNER_ID")
private String ownerId;
@Column(name = "TRAINER_ID")
private String trainerId;
@Column(name = "ADDED_ON")
private Timestamp addedOn;
@Column(name = "MODIFIED_ON")
private Timestamp modifiedOn;
@Column(name = "ADDED_BY")
private String addedBy;
@Column(name = "MODIFIED_BY")
private String modifiedBy;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "USER_ROLES", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"),
inverseJoinColumns =
@JoinColumn(name =
"ROLE_ID", referencedColumnName = "ROLE_ID"))
List<RoleEntity> roles;
@OneToOne(
mappedBy = "user",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private UserStatisticsEntity userStatisticsEntity;
here is the RoleClass :
public class RoleEntity implements GrantedAuthority {
@Id
@Column(name="ROLE_ID")
private String roleId;
@Column(name="ROLE_NAME")
private String roleName;
@ManyToMany(mappedBy = "roles")
private List<UserEntity> users;
@Override
public String getAuthority() {
return this.roleId;
}
}
I would like to fetch all users belonging to a particular role and also be able to add dynamic where clauses on name, mobile, email along with paging etc.
My current code looks like this to fetch selected fields of Users with dynamic where clauses and pagination :
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<TrainerDTO> criteriaQuery = criteriaBuilder.createQuery(TrainerDTO.class);
Root<UserEntity> main = criteriaQuery.from(UserEntity.class);
criteriaQuery.multiselect(main.get("id"), main.get("name"), main.get("email"), main.get("ownerId"), main.get(
"mobile"),
main.get("addedBy"), main.get("modifiedBy"), main.get("addedOn"), main.get("modifiedOn"))
.orderBy(criteriaBuilder.desc(main.get("addedOn")))
.distinct(true);
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(queryParams.get("mobile"))) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(main.get("mobile"), queryParams.get("mobile"))));
}
if (StringUtils.isNotBlank(queryParams.get("name"))) {
predicates.add(criteriaBuilder.and(criteriaBuilder.like(main.get("name"),
"%" + queryParams.get("name") + "%")));
}
if (StringUtils.isNotBlank(queryParams.get("email"))) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(main.get("email"), queryParams.get("email"))));
}
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
log.info("TrainerDAO::getAllTrainersPaginatedForOwner Query created...");
TypedQuery<TrainerDTO> query = entityManager.createQuery(criteriaQuery);
query.setFirstResult(pageNumber - 1);
query.setMaxResults(pageSize);
return query.getResultList();
I am having two issues here :
- How do I get all users which have a certain role? Suppose I need to find all users which have a Role with ROLE_ID = "ROLE_ADMIN".
- In my pagination implementation, the last item in repeated on the next page. Suppose User1 was the last item on page 1, he is coming as first item on page 2 as well.
Please suggest on how to proceed further. All help would be appreciated.
回答1:
Here is my way would be like this:
Issue 1:
You need to reach RoleEntity to check if the role_id is equal to "ROLE_ADMIN", so you need to fetch roles from RoleEntity first and get all the information there.
After you created main object:
Fetch<UserEntity, RoleEntity> fetchedRoles = main.fetch("roles", JoinType.LEFT);
- You will append your condition to your predicates list;
predicates.add(criteriaBuilder.equal( fetchedRoles.get( "roleId" ), "ROLE_ADMIN"));
Issue 2:
I will try to share what I would do in this case to help you solve the issue.
Let's say you create the query here, in this method with pageable object, you want to return Page
private Page<Books> getUsersWithAdminRole(String... parameters, Pageable pageable){
//...
List<UserEntity> result = entityManager.createQuery(criteria).setFirstResult((int) pageable.getOffset()).setMaxResults(pageable.getPageSize()).getResultList();
CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
Root<UserEntity> userCount = countQuery.from(UserEntity.class);
countQuery.select(criteriaBuilder.count(userCount)).where(criteriaBuilder.and(predicates.toArray(newPredicate[predicates.size()])));
Long count = entityManager.createQuery(countQuery).getSingleResult();
Page<UserEntity> userPage = new PageImpl<>(result, pageable, count);
return userPage;
}
I hope, it is helpful
来源:https://stackoverflow.com/questions/61850249/need-to-find-all-users-for-a-specific-role-jpa-criteria-api