Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; // << add this
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface DepartmentRepository extends JpaRepository<Department, Long> {
public interface DepartmentRepository extends JpaRepository<Department, Long>, JpaSpecificationExecutor<Department> {

Department findByDepartmentCode(String departmentCode);


@Query(value = """
select dep from Department dep
where ( :#{#criteria.departmentCode} IS NULL OR LOWER(dep.departmentCode) LIKE LOWER( CONCAT(:#{#criteria.departmentCode}, '%') ) )
and ( :#{#criteria.departmentName} IS NULL OR LOWER(dep.departmentName) LIKE LOWER( CONCAT(:#{#criteria.departmentName}, '%') ) )
and ( :#{#criteria.departmentDescription} IS NULL OR LOWER(dep.departmentDescription) LIKE LOWER( CONCAT('%', :#{#criteria.departmentDescription}, '%') ) )
where ( :#{#criteria.departmentCode} IS NULL OR LOWER(dep.departmentCode) LIKE LOWER(CONCAT(:#{#criteria.departmentCode}, '%')) )
and ( :#{#criteria.departmentName} IS NULL OR LOWER(dep.departmentName) LIKE LOWER(CONCAT(:#{#criteria.departmentName}, '%')) )
and ( :#{#criteria.departmentDescription} IS NULL OR LOWER(dep.departmentDescription) LIKE LOWER(CONCAT('%', :#{#criteria.departmentDescription}, '%')) )
""")
Page<Department> getAllDepartmentsUsingPagination(
@Param("criteria") DepartmentSearchCriteriaDTO departmentSearchCriteriaDTO,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,27 @@ public DepartmentDTO createDepartment(DepartmentDTO departmentDTO) {
}

@Override
public Page<DepartmentDTO> getAllDepartmentsUsingPagination(
DepartmentSearchCriteriaDTO departmentSearchCriteriaDTO) {
public Page<DepartmentDTO> getAllDepartmentsUsingPagination(DepartmentSearchCriteriaDTO departmentSearchCriteriaDTO) {


Integer page = departmentSearchCriteriaDTO.getPage();
Integer size = departmentSearchCriteriaDTO.getSize();
// defensive defaults
Integer page = departmentSearchCriteriaDTO.getPage() == null ? 0 : departmentSearchCriteriaDTO.getPage();
Integer size = departmentSearchCriteriaDTO.getSize() == null ? 10 : departmentSearchCriteriaDTO.getSize();
List<SortItem> sortList = departmentSearchCriteriaDTO.getSortList();

// this pageable will be used for the pagination.
// create Pageable using existing utility (keeps your sorting logic)
Pageable pageable = Utils.createPageableBasedOnPageAndSizeAndSorting(sortList, page, size);

Page<Department> recordsFromDb = departmentRepository.getAllDepartmentsUsingPagination(departmentSearchCriteriaDTO, pageable);
// Build Specification from criteria
var spec = com.ainigma100.departmentapi.specification.DepartmentSpecification.fromCriteria(departmentSearchCriteriaDTO);

// Query repository using Specification + Pageable
Page<com.ainigma100.departmentapi.entity.Department> recordsFromDb =
departmentRepository.findAll(spec, pageable);

// Map entity list to DTO list
List<DepartmentDTO> result = departmentMapper.departmentToDepartmentDto(recordsFromDb.getContent());

// Return a page preserving the paging metadata
return new PageImpl<>(result, pageable, recordsFromDb.getTotalElements());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.ainigma100.departmentapi.specification;

import com.ainigma100.departmentapi.dto.DepartmentSearchCriteriaDTO;
import com.ainigma100.departmentapi.entity.Department;
import jakarta.persistence.criteria.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
* Build a Specification<Department> from DepartmentSearchCriteriaDTO.
* - departmentCode: prefix match (case-insensitive)
* - departmentName: contains match (case-insensitive)
* - departmentDescription: contains match (case-insensitive)
*
* Extend this class if you want more operators (equals, ranges, enums, etc).
*/
public final class DepartmentSpecification {

private DepartmentSpecification() {}

public static Specification<Department> fromCriteria(DepartmentSearchCriteriaDTO criteria) {
return (Root<Department> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
List<Predicate> predicates = new ArrayList<>();

if (criteria == null) {
return cb.conjunction();
}

// departmentCode: prefix match (deptCode starts with value), case-insensitive
if (StringUtils.hasText(criteria.getDepartmentCode())) {
predicates.add(cb.like(cb.lower(root.get("departmentCode")), criteria.getDepartmentCode().toLowerCase() + "%"));
}

// departmentName: contains, case-insensitive
if (StringUtils.hasText(criteria.getDepartmentName())) {
predicates.add(cb.like(cb.lower(root.get("departmentName")), "%" + criteria.getDepartmentName().toLowerCase() + "%"));
}

// departmentDescription: contains, case-insensitive
if (StringUtils.hasText(criteria.getDepartmentDescription())) {
predicates.add(cb.like(cb.lower(root.get("departmentDescription")), "%" + criteria.getDepartmentDescription().toLowerCase() + "%"));
}

// Combine predicates (AND)
return predicates.isEmpty() ? cb.conjunction() : cb.and(predicates.toArray(new Predicate[0]));
};
}
}