flowable/flowable-engine · error · TypeException
JDBC requires that the JdbcType must be specified for all nu
Error message
JDBC requires that the JdbcType must be specified for all nullable parameters.
What it means
A MyBatis TypeException thrown by FlowableStringTypeHandler.setParameter when binding a null String parameter whose JdbcType is unspecified. Some JDBC drivers cannot bind NULL without a type hint, so Flowable's type handler refuses to proceed rather than let the driver fail opaquely.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/db/FlowableStringTypeHandler.java:25
import java.sql.Types;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeException;
public class FlowableStringTypeHandler extends BaseTypeHandler<String> {
protected boolean useDefaultJdbcType;
public FlowableStringTypeHandler(boolean useDefaultJdbcType) {
this.useDefaultJdbcType = useDefaultJdbcType;
}
@Override
public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
if (jdbcType == null) {
throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
}
try {
if (useDefaultJdbcType) {
JdbcType finalJdbcType = null;
if (jdbcType.equals(JdbcType.NVARCHAR)) {
finalJdbcType = JdbcType.VARCHAR;
} else {
finalJdbcType = jdbcType;
}
ps.setNull(i, finalJdbcType.TYPE_CODE);
} else {
ps.setNull(i, Types.NULL);
}
} catch (SQLException e) {
throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . "
+ "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. "
+ "Cause: " + e, e);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Add an explicit jdbcType to nullable parameter mappings, e.g. #{name,jdbcType=VARCHAR}.
- Set MyBatis configuration property jdbcTypeForNull=VARCHAR so nulls always get a type.
- Ensure variables set into the engine are non-null where the mapping has no jdbcType.
- Verify the JDBC driver supports the configured JdbcType for null binding.
Example fix
// before (mapper XML)
#{description}
// after
#{description,jdbcType=VARCHAR} Defensive patterns
Strategy: validation
Validate before calling
if (value == null) ensureMapperDeclaresJdbcType("name", "VARCHAR"); // or set jdbcTypeForNull=VARCHAR globally Type guard
boolean needsJdbcType(Object v) { return v == null; } // if true, mapping must declare jdbcType Try / catch
catch (TypeException e) { if (e.getMessage().contains("JdbcType must be specified")) { /* add jdbcType to mapping or set jdbcTypeForNull */ } throw e; } Prevention
- Always add jdbcType=VARCHAR to nullable #{...} mappings.
- Set MyBatis jdbcTypeForNull=VARCHAR.
- Avoid passing null engine variables where mappings lack jdbcType.
When it happens
Trigger: Executing a mapped statement that passes a null String into a prepared-statement parameter while the mapping/MyBatis global jdbcTypeForNull yields jdbcType == null; custom SQL/XML mappings omitting jdbcType=... on a nullable parameter.
Common situations: Custom MyBatis mapper XML with #{prop} and no jdbcType attribute where the value is null; overriding jdbcTypeForNull to something invalid; reusing Flowable's type handler in custom persistence code.
Related errors
- Error setting null for parameter #${i} with JdbcType ${jdbcT
- Error setting non null for parameter #${i} with JdbcType ${j
- Exception while initializing Database connection
- There are app definitions with key = '' and version = ''
- CmmnRuntimeService cannot be null, Obtain your builder insta
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/7c81c0a797eb7661.
Report an issue: GitHub.