class BudgetDetailJdbcRepository extends JdbcRepository {

    public Pagination<BudgetDetail> search(final BudgetDetailSearch domain) {
        final BudgetDetailSearchEntity budgetDetailSearchEntity = new BudgetDetailSearchEntity();
        budgetDetailSearchEntity.toEntity(domain);

        String searchQuery = "select :selectfields from :tablename :condition  :orderby   ";

        final Map<String, Object> paramValues = new HashMap<>();
        final StringBuffer params = new StringBuffer();

        if (budgetDetailSearchEntity.getSortBy() != null && !budgetDetailSearchEntity.getSortBy().isEmpty()) {
            validateSortByOrder(budgetDetailSearchEntity.getSortBy());
            validateEntityFieldName(budgetDetailSearchEntity.getSortBy(), BudgetEntity.class);
        }

        String orderBy = "order by id";
        if (budgetDetailSearchEntity.getSortBy() != null && !budgetDetailSearchEntity.getSortBy().isEmpty())
            orderBy = "order by " + budgetDetailSearchEntity.getSortBy();

        searchQuery = searchQuery.replace(":tablename", BudgetDetailEntity.TABLE_NAME);

        searchQuery = searchQuery.replace(":selectfields", " * ");

        // implement jdbc specfic search
        if (budgetDetailSearchEntity.getTenantId() != null) {
			if (params.length() > 0) {
				params.append(" and ");
			}
			params.append("tenantId =:tenantId");
			paramValues.put("tenantId", budgetDetailSearchEntity.getTenantId());
		}
        if (budgetDetailSearchEntity.getId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("id =:id");
            paramValues.put("id", budgetDetailSearchEntity.getId());
        }
        if (budgetDetailSearchEntity.getBudgetId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("budgetid =:budget");
            paramValues.put("budget", budgetDetailSearchEntity.getBudgetId());
        }
        if (budgetDetailSearchEntity.getBudgetGroupId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("budgetGroupid =:budgetGroup");
            paramValues.put("budgetGroup", budgetDetailSearchEntity.getBudgetGroupId());
        }
        if (budgetDetailSearchEntity.getUsingDepartmentId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("usingDepartmentid =:usingDepartment");
            paramValues.put("usingDepartment", budgetDetailSearchEntity.getUsingDepartmentId());
        }
        if (budgetDetailSearchEntity.getExecutingDepartmentId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("executingDepartmentid =:executingDepartment");
            paramValues.put("executingDepartment", budgetDetailSearchEntity.getExecutingDepartmentId());
        }
        if (budgetDetailSearchEntity.getFundId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("fundid =:fund");
            paramValues.put("fund", budgetDetailSearchEntity.getFundId());
        }
        if (budgetDetailSearchEntity.getFunctionId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("functionid =:function");
            paramValues.put("function", budgetDetailSearchEntity.getFunctionId());
        }
        if (budgetDetailSearchEntity.getSchemeId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("schemeid =:scheme");
            paramValues.put("scheme", budgetDetailSearchEntity.getSchemeId());
        }
        if (budgetDetailSearchEntity.getSubSchemeId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("subSchemeid =:subScheme");
            paramValues.put("subScheme", budgetDetailSearchEntity.getSubSchemeId());
        }
        if (budgetDetailSearchEntity.getFunctionaryId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("functionaryid =:functionary");
            paramValues.put("functionary", budgetDetailSearchEntity.getFunctionaryId());
        }
        if (budgetDetailSearchEntity.getBoundaryId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("boundaryid =:boundary");
            paramValues.put("boundary", budgetDetailSearchEntity.getBoundaryId());
        }
        if (budgetDetailSearchEntity.getOriginalAmount() != null
                && 0 != budgetDetailSearchEntity.getOriginalAmount().compareTo(BigDecimal.ZERO)) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("originalAmount =:originalAmount");
            paramValues.put("originalAmount", budgetDetailSearchEntity.getOriginalAmount());
        }
        if (budgetDetailSearchEntity.getApprovedAmount() != null
                && 0 != budgetDetailSearchEntity.getApprovedAmount().compareTo(BigDecimal.ZERO)) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("approvedAmount =:approvedAmount");
            paramValues.put("approvedAmount", budgetDetailSearchEntity.getApprovedAmount());
        }
        if (budgetDetailSearchEntity.getBudgetAvailable() != null
                && 0 != budgetDetailSearchEntity.getBudgetAvailable().compareTo(BigDecimal.ZERO)) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("budgetAvailable =:budgetAvailable");
            paramValues.put("budgetAvailable", budgetDetailSearchEntity.getBudgetAvailable());
        }
        if (budgetDetailSearchEntity.getAnticipatoryAmount() != null
                && 0 != budgetDetailSearchEntity.getAnticipatoryAmount().compareTo(BigDecimal.ZERO)) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("anticipatoryAmount =:anticipatoryAmount");
            paramValues.put("anticipatoryAmount", budgetDetailSearchEntity.getAnticipatoryAmount());
        }
        if (budgetDetailSearchEntity.getPlanningPercent() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("planningPercent =:planningPercent");
            paramValues.put("planningPercent", budgetDetailSearchEntity.getPlanningPercent());
        }
        if (budgetDetailSearchEntity.getStatusId() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("statusid =:status");
            paramValues.put("status", budgetDetailSearchEntity.getStatusId());
        }
        if (budgetDetailSearchEntity.getDocumentNumber() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("documentNumber =:documentNumber");
            paramValues.put("documentNumber", budgetDetailSearchEntity.getDocumentNumber());
        }
        if (budgetDetailSearchEntity.getUniqueNo() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("uniqueNo =:uniqueNo");
            paramValues.put("uniqueNo", budgetDetailSearchEntity.getUniqueNo());
        }
        if (budgetDetailSearchEntity.getMaterializedPath() != null) {
            if (params.length() > 0)
                params.append(" and ");
            params.append("materializedPath =:materializedPath");
            paramValues.put("materializedPath", budgetDetailSearchEntity.getMaterializedPath());
        }

        Pagination<BudgetDetail> page = new Pagination<>();
        if (budgetDetailSearchEntity.getOffset() != null)
            page.setOffset(budgetDetailSearchEntity.getOffset());
        if (budgetDetailSearchEntity.getPageSize() != null)
            page.setPageSize(budgetDetailSearchEntity.getPageSize());

        if (params.length() > 0)
            searchQuery = searchQuery.replace(":condition", " where " + params.toString());
        else
            searchQuery = searchQuery.replace(":condition", "");

        searchQuery = searchQuery.replace(":orderby", orderBy);

        page = (Pagination<BudgetDetail>) getPagination(searchQuery, page, paramValues);
        searchQuery = searchQuery + " :pagination";

        searchQuery = searchQuery.replace(":pagination",
                "limit " + page.getPageSize() + " offset " + page.getOffset() * page.getPageSize());

        final BeanPropertyRowMapper row = new BeanPropertyRowMapper(BudgetDetailEntity.class);

        final List<BudgetDetailEntity> budgetDetailEntities = namedParameterJdbcTemplate.query(searchQuery.toString(),
                paramValues, row);

        page.setTotalResults(budgetDetailEntities.size());

        final List<BudgetDetail> budgetdetails = new ArrayList<BudgetDetail>();
        for (final BudgetDetailEntity budgetDetailEntity : budgetDetailEntities)
            budgetdetails.add(budgetDetailEntity.toDomain());
        page.setPagedData(budgetdetails);

        return page;
    }

    public  BudgetDetailJdbcRepository(final NamedParameterJdbcTemplate namedParameterJdbcTemplate, JdbcTemplate jdbcTemplate);

}