spring-projects / spring-projects/spring-batch

JdbcPagingItemReader - When using sortKeys with alias, I think it should paging by column name rather than alias in the select clause.

Open
#4,573 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

has: minimal-example status: feedback-provided type: feature
Dominant language
Java
Stars
3k
Forks
2.5k
Avg merge
6d 53m
Merged PRs (30d)
3

Description

@Bean
@StepScope
public JdbcPagingItemReader<Point> reader() {

    return new JdbcPagingItemReaderBuilder<Point>()
            .name("reader")
            .pageSize(chunkSize)
            .fetchSize(chunkSize)
            .dataSource(datasource)
            .rowMapper(pointRowMapper)
            .parameterValues(parameters)
            .queryProvider(pagingQueryProvider())
            .build();
}

@Bean
public PagingQueryProvider pagingQueryProvider() {

    SqlPagingQueryProviderFactoryBean queryProvider = new SqlPagingQueryProviderFactoryBean();
    queryProvider.setDataSource(datasource);
    queryProvider.setSelectClause("place_id, user_id as member_id, points");
    queryProvider.setFromClause("user_point");
    queryProvider.setWhereClause("place_id = :place_id");
    queryProvider.setSortKeys(sortKeyAsc("place_id", "member_id"));

    try {
        return queryProvider.getObject();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

In mysqal datasource,
When you run the above code, the queries written in Current Behavior are sorted.

However, I think it should be done like the query in Expected Behavior

Expected Behavior

SELECT place_id, user_id as member_id, point 
FROM user_point 
WHERE (user_point.place_id = ?) 
AND ((place_id > ?) OR (place_id = ? AND user_id > ?)) # member_id -> user_id
ORDER BY place_id ASC, member_id ASC 
LIMIT ?

Current Behavior

SELECT place_id, user_id as member_id, point 
FROM user_point 
WHERE (user_point.place_id = ?) 
AND ((place_id > ?) OR (place_id = ? AND member_id > ?)) 
ORDER BY place_id ASC, member_id ASC 
LIMIT ?

Context

when using jdbcPagingItemReader and PagingQueryProvider, paging and sorting are done based on the sortKey in the where clause.
If an alias is used in the select clause and designated as the sortKey, the column name used in the where clause becomes the alias, leading to an exception since the database cannot find it.

This situation is awkward. Typically, the reason for using aliases in a select clause is for use in an order by clause. However, using aliases for paging causes problems. So I think it might be necessary to modify the paging logic to use actual column names rather than aliases.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The relevant entry points are SqlPagingQueryProviderFactoryBean, PagingQueryProvider, and JdbcPagingItemReader; start by tracing how sortKeys are used to build the paging WHERE clause and ORDER BY for MySQL. Compare generated SQL for an aliased select column with the reported examples. Done means the paging predicate resolves the underlying column without breaking ordering or pagination.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, mysql, spring, sql
Domain
backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.