Fixed configuration of sort keys in JdbcPagingItemReader

The JdbcPagingItemReader allows the configuration of multiple sort keys.
If a user configures one of those columns with a table alias, it causes
issues.  This update strips the aliases off of the sort keys.
This commit is contained in:
Michael Minella
2014-09-16 14:42:35 -05:00
parent ab41ce09cc
commit 694998f1b3
4 changed files with 42 additions and 13 deletions

View File

@@ -16,9 +16,8 @@
package org.springframework.batch.item.database;
import java.util.Map;
import javax.sql.DataSource;
import java.util.Map;
/**
@@ -95,4 +94,11 @@ public interface PagingQueryProvider {
* @return The string to be used for a parameterized query.
*/
String getSortKeyPlaceHolder(String keyName);
/**
* The sort key (unique single column name) without alias.
*
* @return the sort key used to order the query (without alias)
*/
Map<String, Order> getSortKeysWithoutAliases();
}

View File

@@ -248,4 +248,27 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
}
}
/**
*
* @return sortKey key to use to sort and limit page content (without alias)
*/
@Override
public Map<String, Order> getSortKeysWithoutAliases() {
Map<String, Order> sortKeysWithoutAliases = new LinkedHashMap<String, Order>();
for (Map.Entry<String, Order> sortKeyEntry : sortKeys.entrySet()) {
String key = sortKeyEntry.getKey();
int separator = key.indexOf('.');
if (separator > 0) {
int columnIndex = separator + 1;
if (columnIndex < key.length()) {
sortKeysWithoutAliases.put(key.substring(columnIndex), sortKeyEntry.getValue());
}
} else {
sortKeysWithoutAliases.put(sortKeyEntry.getKey(), sortKeyEntry.getValue());
}
}
return sortKeysWithoutAliases;
}
}

View File

@@ -16,14 +16,14 @@
package org.springframework.batch.item.database.support;
import org.springframework.batch.item.database.Order;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.batch.item.database.Order;
import org.springframework.util.StringUtils;
/**
* Utility class that generates the actual SQL statements used by query
* providers.
@@ -246,7 +246,7 @@ public class SqlPagingQueryUtils {
* @return a String that can be appended to an ORDER BY clause.
*/
public static String buildSortClause(AbstractSqlPagingQueryProvider provider) {
return buildSortClause(provider.getSortKeys());
return buildSortClause(provider.getSortKeysWithoutAliases());
}
/**
@@ -285,7 +285,7 @@ public class SqlPagingQueryUtils {
*/
public static void buildSortConditions(
AbstractSqlPagingQueryProvider provider, StringBuilder sql) {
List<Map.Entry<String, Order>> keys = new ArrayList<Map.Entry<String,Order>>(provider.getSortKeys().entrySet());
List<Map.Entry<String, Order>> keys = new ArrayList<Map.Entry<String,Order>>(provider.getSortKeysWithoutAliases().entrySet());
List<String> clauses = new ArrayList<String>();
for(int i = 0; i < keys.size(); i++) {
@@ -336,7 +336,7 @@ public class SqlPagingQueryUtils {
String prefix = "";
for (Map.Entry<String, Order> sortKey : provider.getSortKeys().entrySet()) {
for (Map.Entry<String, Order> sortKey : provider.getSortKeysWithoutAliases().entrySet()) {
select.append(prefix);
prefix = ", ";

View File

@@ -15,14 +15,14 @@
*/
package org.springframework.batch.item.database.support;
import static org.junit.Assert.assertEquals;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.batch.item.database.Order;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.batch.item.database.Order;
import static org.junit.Assert.assertEquals;
/**
* @author Thomas Risberg
@@ -111,7 +111,7 @@ public class SqlWindowingPagingQueryProviderTests extends AbstractSqlPagingQuery
sortKeys.put("E.id", Order.DESCENDING);
pagingQueryProvider.setSortKeys(sortKeys);
String sql="SELECT TMP_SUB.id FROM ( SELECT E.id, ROW_NUMBER() OVER ( ORDER BY E.id DESC) AS ROW_NUMBER FROM foo_e E, foo_i I WHERE E.id=I.id) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER = 1 ORDER BY TMP_SUB.id DESC";
String sql="SELECT TMP_SUB.id FROM ( SELECT E.id, ROW_NUMBER() OVER ( ORDER BY id DESC) AS ROW_NUMBER FROM foo_e E, foo_i I WHERE E.id=I.id) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER = 1 ORDER BY TMP_SUB.id DESC";
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
assertEquals(sql, s);
}