pagehelper-org/Mybatis-PageHelper · critical · PageException
Failed to get the BoundSql property additionalParameters
Error message
Failed to get the BoundSql property additionalParameters: ${e} What it means
ExecutorUtil uses reflection to access the private field BoundSql.additionalParameters, which MyBatis does not expose via a public API in older versions. During class initialization it looks up this field; if the loaded mybatis jar's BoundSql class does not declare it (incompatible/very new or shaded mybatis version), the static initializer throws this PageException and the class fails to load.
Solutions
- Align versions: use a pagehelper release compatible with your mybatis version (check pagehelper's documented mybatis compatibility matrix)
- Run mvn dependency:tree (or gradle dependencies) and remove duplicate/conflicting mybatis jars so only one expected version is on the classpath
- Downgrade/upgrade mybatis to a version whose BoundSql declares additionalParameters
- Upgrade pagehelper to the latest release, which supports newer mybatis APIs
- If truly blocked, report to pagehelper issues — newer pagehelper versions avoid this reflection via mybatis's own accessors
Example fix
// before (pom.xml) <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.99</version></dependency> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.4</version></dependency> // after (compatible pair) <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.2</version></dependency>
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify compatibility at startup before relying on pagination
try {
Class.forName("com.github.pagehelper.util.ExecutorUtil");
} catch (Throwable t) {
throw new IllegalStateException("PageHelper incompatible with loaded mybatis BoundSql: " + t, t);
} Try / catch
try (SqlSession session = factory.openSession()) {
return mapper.selectPaged(params);
} catch (PageException e) {
if (e.getMessage().contains("additionalParameters")) {
throw new IllegalStateException("mybatis/pagehelper version mismatch — align versions", e);
}
throw e;
} Prevention
- Pin pagehelper and mybatis to a documented compatible version pair in your BOM
- Run mvn dependency:tree in CI to detect duplicate mybatis artifacts
- Smoke-test pagination at application startup, not only on first page request
- Avoid shaded/repackaged mybatis jars
When it happens
Trigger: Application startup when the ExecutorUtil class is first loaded against a mybatis version whose BoundSql class lacks the 'additionalParameters' field — e.g. a major mybatis upgrade, a shaded/repackaged mybatis, or mismatched pagehelper/mybatis dependency versions.
Common situations: Upgrading MyBatis past the version PageHelper was built for; duplicate mybatis jars on the classpath where the wrong one wins; OSGi/shaded deployments hiding the field.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Get the ProviderSqlSource property value of…
- The pagination query parameter failed to be processed!
- error initializing helper dialectclass
- Class must provide a constructor without parameters
- unable to get paginated query parameters!
AI-assisted analysis of pagehelper-org/Mybatis-PageHelper@c692616c5b (2026-09-08).
Data as JSON: /api/errors/423d724ec43bce2c.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/com/github/pagehelper/util/ExecutorUtil.java:58
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
/**
* @author liuzenghui
*/
public abstract class ExecutorUtil {
private static Field additionalParametersField;
private static Field providerMethodArgumentNamesField;
static {
try {
additionalParametersField = BoundSql.class.getDeclaredField("additionalParameters");
additionalParametersField.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new PageException("Failed to get the BoundSql property additionalParameters: " + e, e);
}
try {
//兼容低版本
providerMethodArgumentNamesField = ProviderSqlSource.class.getDeclaredField("providerMethodArgumentNames");
providerMethodArgumentNamesField.setAccessible(true);
} catch (NoSuchFieldException ignore) {
}
}
/**
* 获取 BoundSql 属性值 additionalParameters
*
* @param boundSql
* @return
*/
public static Map<String, Object> getAdditionalParameter(BoundSql boundSql) {
try {
return (Map<String, Object>) additionalParametersField.get(boundSql);View on GitHub (pinned to c692616c5b)