mybatis/mybatis-3 · error · ExecutorException
SelectKey returned no data.
Error message
SelectKey returned no data.
What it means
SelectKeyGenerator runs the <selectKey> statement (before or after the insert) and expects it to return exactly one row containing the key value. An empty result means no key could be obtained, so MyBatis throws this ExecutorException instead of silently leaving the keyProperty unset.
Source
Thrown at src/main/java/org/apache/ibatis/executor/keygen/SelectKeyGenerator.java:69
@Override
public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
if (!executeBefore) {
processGeneratedKeys(executor, ms, parameter);
}
}
private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) {
try {
if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) {
String[] keyProperties = keyStatement.getKeyProperties();
final Configuration configuration = ms.getConfiguration();
final MetaObject metaParam = configuration.newMetaObject(parameter);
// Do not close keyExecutor.
// The transaction will be closed by parent executor.
Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE);
List<Object> values = keyExecutor.query(keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
if (values.isEmpty()) {
throw new ExecutorException("SelectKey returned no data.");
}
if (values.size() > 1) {
throw new ExecutorException("SelectKey returned more than one value.");
} else {
MetaObject metaResult = configuration.newMetaObject(values.get(0));
if (keyProperties.length == 1) {
if (metaResult.hasGetter(keyProperties[0])) {
setValue(metaParam, keyProperties[0], metaResult.getValue(keyProperties[0]));
} else {
// no getter for the property - maybe just a single value object
// so try that
setValue(metaParam, keyProperties[0], values.get(0));
}
} else {
handleMultipleProperties(keyProperties, metaParam, metaResult);
}
}
}View on GitHub (pinned to 008069adb1)
Solutions
- Run the selectKey SQL manually with the same parameters to see why it returns zero rows
- Ensure the sequence/table referenced by the selectKey exists and is queryable in that environment
- Add a resultType/resultMap to the <selectKey> so the row is actually materialized
- Guarantee the selectKey SQL always returns exactly one row (e.g. FROM DUAL / LIMIT 1)
Example fix
<!-- before: returns 0 rows on empty table -->
<selectKey keyProperty="id" resultType="long" order="BEFORE">
SELECT MAX(id)+1 FROM users WHERE tenant = #{tenant}
</selectKey>
<!-- after: always one row -->
<selectKey keyProperty="id" resultType="long" order="BEFORE">
SELECT nextval('user_seq')
</selectKey> Defensive patterns
Strategy: validation
Validate before calling
// Smoke-test the selectKey SQL during app startup in the target schema
Long key = jdbcTemplate.queryForObject("SELECT nextval('user_seq')", Long.class);
if (key == null) throw new IllegalStateException("selectKey source is not returning rows"); Try / catch
try { mapper.insert(user); } catch (PersistenceException e) { if (String.valueOf(e.getMessage()).contains("SelectKey returned no data")) { log.error("selectKey SQL returned 0 rows — verify sequence/table"); } throw e; } Prevention
- Always give <selectKey> a resultType and a statement that provably returns one row
- Run the selectKey SQL in CI against a real schema
When it happens
Trigger: A <selectKey> whose SQL returns no rows for the current input, e.g. SELECT seq.NEXTVAL FROM DUAL on an exhausted/broken sequence, a lookup query (SELECT id FROM t WHERE ...) matching nothing, or a statement type misconfigured as a query returning void.
Common situations: Oracle/PostgreSQL sequence selects when the sequence object is missing or renamed; MAX(id)+1 strategies on empty tables with a WHERE filter; resultType on selectKey missing so the row maps to null.
Related errors
- SelectKey returned more than one value.
- Error getting generated key or setting result to parameter o
- Error selecting key or setting result to parameter object. C
- If SelectKey has key columns, the number must match the numb
- No setter found for the keyProperty '" + property + "' in "
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/1772528ca213a91a.
Report an issue: GitHub.