class ChartOfAccountDetailJdbcRepository extends JdbcRepository {

    public Pagination<ChartOfAccountDetail> search(ChartOfAccountDetailSearch domain) {
        ChartOfAccountDetailSearchEntity chartOfAccountDetailSearchEntity = new ChartOfAccountDetailSearchEntity();
        chartOfAccountDetailSearchEntity.toEntity(domain);

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

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

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

        String orderBy = "order by chartOfAccountId";
        if (chartOfAccountDetailSearchEntity.getSortBy() != null
                && !chartOfAccountDetailSearchEntity.getSortBy().isEmpty()) {
            orderBy = "order by " + chartOfAccountDetailSearchEntity.getSortBy();
        }

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

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

        // implement jdbc specfic search
        if (chartOfAccountDetailSearchEntity.getTenantId() != null) {
            if (params.length() > 0) {
                params.append(" and ");
            }
            params.append("tenantId =:tenantId");
            paramValues.put("tenantId", chartOfAccountDetailSearchEntity.getTenantId());
        }
        if (chartOfAccountDetailSearchEntity.getId() != null) {
            if (params.length() > 0) {
                params.append(" and ");
            }
            params.append("id =:id");
            paramValues.put("id", chartOfAccountDetailSearchEntity.getId());
        }
        if (chartOfAccountDetailSearchEntity.getIds() != null) {
            if (params.length() > 0) {
                params.append(" and ");
            }
            params.append("id in(:ids) ");
            paramValues.put("ids", new ArrayList<String>(Arrays.asList(chartOfAccountDetailSearchEntity.getIds().split(","))));
        }

        if (chartOfAccountDetailSearchEntity.getChartOfAccountIds() != null) {
            if (params.length() > 0) {
                params.append(" and ");
            }
            params.append("chartOfAccountId in(:chartOfAccountIds) ");
            paramValues.put("chartOfAccountIds",
                    new ArrayList<String>(Arrays.asList(chartOfAccountDetailSearchEntity.getChartOfAccountIds().split(","))));
        }
        if (chartOfAccountDetailSearchEntity.getChartOfAccountId() != null) {
            if (params.length() > 0) {
                params.append(" and ");
            }
            params.append("chartOfAccountId =:chartOfAccount");
            paramValues.put("chartOfAccount", chartOfAccountDetailSearchEntity.getChartOfAccountId());
        }
        if (chartOfAccountDetailSearchEntity.getAccountDetailTypeId() != null) {
            if (params.length() > 0) {
                params.append(" and ");
            }
            params.append("accountDetailTypeId =:accountDetailType");
            paramValues.put("accountDetailType", chartOfAccountDetailSearchEntity.getAccountDetailTypeId());
        }

        Pagination<ChartOfAccountDetail> page = new Pagination<>();
        if (chartOfAccountDetailSearchEntity.getOffset() != null) {
            page.setOffset(chartOfAccountDetailSearchEntity.getOffset());
        }
        if (chartOfAccountDetailSearchEntity.getPageSize() != null) {
            page.setPageSize(chartOfAccountDetailSearchEntity.getPageSize());
        }

        if (params.length() > 0) {

            searchQuery = searchQuery.replace(":condition", " where " +
                    params.toString());

        } else

            searchQuery = searchQuery.replace(":condition", "");

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

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

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

        BeanPropertyRowMapper row = new BeanPropertyRowMapper(ChartOfAccountDetailEntity.class);
        StringBuffer adtIds = new StringBuffer();

        List<ChartOfAccountDetailEntity> chartOfAccountDetailEntities = namedParameterJdbcTemplate
                .query(searchQuery.toString(), paramValues, row);

        page.setTotalResults(chartOfAccountDetailEntities.size());

        List<ChartOfAccountDetail> chartofaccountdetails = new ArrayList<>();
        for (ChartOfAccountDetailEntity chartOfAccountDetailEntity : chartOfAccountDetailEntities) {
            if (adtIds.length() >= 1)
                adtIds.append(",");

            adtIds.append(chartOfAccountDetailEntity.getAccountDetailTypeId());
            chartofaccountdetails.add(chartOfAccountDetailEntity.toDomain());
        }

        populateAccountDetailTypes(chartofaccountdetails, adtIds.toString());

        page.setPagedData(chartofaccountdetails);

        return page;
    }

    public  ChartOfAccountDetailJdbcRepository(NamedParameterJdbcTemplate namedParameterJdbcTemplate,
            AccountDetailTypeJdbcRepository accountDetailTypeJdbcRepository);

}