#Filtering Entities by conditions in a generic and safe way
11 messages · Page 1 of 1 (latest)
⌛ This post has been reserved for your question.
Hey @amber inlet! Please use
/closeor theClose Postbutton above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 720 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
The following is my base class
public class BaseRepository<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements IBaseRepository<T, ID> {
public final Class<T> entityClass;
public BaseRepository(
JpaEntityInformation<T, ?> entityInformation,
EntityManager entityManager
) {
super(
entityInformation,
entityManager
);
this.entityClass = entityInformation.getJavaType();
}
public Page<T> findAllWithFilters(
PaginationParams paginationParams,
Optional<Specification<T>> extraSpecifications
) {
Map<String, String> originalFilters = paginationParams.getFilters();
Map<String, String> mappedFilters = new HashMap<>();
for (var entry : originalFilters.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
var splits = key.split("_");
if (splits.length != 2)
continue;
String dtoField = splits[0];
String operation = splits[1];
String entityField = PaginationFieldMapper.resolveField(
entityClass,
dtoField
);
mappedFilters.put(
entityField + "_" + operation,
value
);
}
Pageable pageable = paginationParams.toPageable();
return extraSpecifications.map(tSpecification -> findAll(
tSpecification.and(GenericSpecification.buildSpecification(mappedFilters)),
pageable
))
.orElseGet(() -> findAll(
GenericSpecification.buildSpecification(mappedFilters),
pageable
));
}
}
@Transactional(readOnly = true)
public BaseResponseEntity<Page<AccountPaginatedDto>> getUsers(
PaginationParams paginationParams
) {
var results = userRepository.findAllWithFilters(
paginationParams,
null
);
var mappedResult = results.map((res) -> {
var dto = new AccountPaginatedDto();
dto.setUsername(res.getUsername());
dto.setEmail(res.getEmail());
dto.setId(String.valueOf(res.getId()));
dto.setFirstName(res.getFirstname());
dto.setLastName(res.getLastname());
return dto;
});
return new BaseResponseEntity<>(mappedResult);
}
as you can see i have added Optional<Specification<T>> extraSpecifications into my method, which the idea is that for example if i want to fetch all users for my table i would fetch all with the filters chosen from frontend + my filters (enabled and not deleted)
coming from C# dotnet, we use Linq, which i can directly add something like
var results = userRepository.findAllWithFilters(
paginationParams,
i=> i.isEnabled && !i.isDeleted
);
i want to do this in a generic way such that i dont have to build classifications class for each entity.
I want it to be clean and safe so for example i dont want to use strings to tell which property i want to filter
I read about jOOQ, QueryDSL but im not sure if that fits what i need, and i want this to be following best practices in java springboot
Any feedback would be greatly appreciated ❤️
You may want to take a look at https://www.baeldung.com/hibernate-criteria-queries-metamodel
thanks a lot i ended up implementing this ^
If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.