apache/beam · error · IllegalArgumentException
Query and Table are mutually exclusive configurations
Error message
Query and Table are mutually exclusive configurations
What it means
The JdbcReadSchemaTransformConfiguration treats readQuery and location (table) as alternatives: a query replaces the table source. If both readQuery and location are set, validate() throws this IllegalArgumentException because the intent is ambiguous.
Solutions
- Remove setLocation() if you want to read with a custom SQL query.
- Remove setReadQuery() if you want to read a whole table (required for partitioned reads).
- Centralize config assembly so only one of the two fields is ever populated.
Example fix
// before
builder().setJdbcUrl(url).setLocation("t1").setReadQuery("SELECT * FROM t1")
// after
builder().setJdbcUrl(url).setReadQuery("SELECT * FROM t1") // drop the table Defensive patterns
Strategy: validation
Validate before calling
if (hasText(config.getReadQuery()) && hasText(config.getLocation())) {
throw new IllegalArgumentException("Set either readQuery or location (table), not both");
} Try / catch
try {
config.validate();
} catch (IllegalArgumentException e) {
if ("Query and Table are mutually exclusive configurations".equals(e.getMessage())) {
throw new IllegalStateException("Config contains both readQuery and table; keep only one", e);
}
throw e;
} Prevention
- Use a builder wrapper that clears location when readQuery is set (and vice versa).
- Audit merged config templates for both keys.
- Default UIs to a single source selector.
When it happens
Trigger: Building the transform with both setReadQuery(...) and setLocation(...) (table) non-empty and then calling from()/validate().
Common situations: Merging default config templates that each populate one field, or UIs that persist the last-selected option without clearing the other.
Related errors
- Either Query or Table must be specified.
- JDBC URL cannot be blank
- Batch size is too large! It should be smaller or equal than
- Column delimiter should be set if headers are present.
- Column headers should be supplied when delimiter is present.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9695483da2e9d494.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/jdbc/src/main/java/org/apache/beam/sdk/io/jdbc/JdbcReadSchemaTransformProvider.java:432
"If JDBC type is not specified, then Driver Class Name and Driver Jars must be specified.");
}
if (!driverClassNamePresent && !jdbcTypePresent) {
throw new IllegalArgumentException(
"One of JDBC Driver class name or JDBC type must be specified.");
}
if (jdbcTypePresent
&& !JDBC_DRIVER_MAP.containsKey(Objects.requireNonNull(jdbcType).toLowerCase())) {
throw new IllegalArgumentException("JDBC type must be one of " + JDBC_DRIVER_MAP.keySet());
}
boolean readQueryPresent = (getReadQuery() != null && !"".equals(getReadQuery()));
boolean locationPresent = (getLocation() != null && !"".equals(getLocation()));
boolean partitionColumnPresent =
(getPartitionColumn() != null && !"".equals(getPartitionColumn()));
// If you specify a readQuery, it is to be used instead of a table.
if (readQueryPresent && locationPresent) {
throw new IllegalArgumentException("Query and Table are mutually exclusive configurations");
}
if (!readQueryPresent && !locationPresent) {
throw new IllegalArgumentException("Either Query or Table must be specified.");
}
// Reading with partitions only supports table argument.
if (partitionColumnPresent && !locationPresent) {
throw new IllegalArgumentException("Table must be specified to read with partitions.");
}
}
public static Builder builder() {
return new AutoValue_JdbcReadSchemaTransformProvider_JdbcReadSchemaTransformConfiguration
.Builder();
}
public abstract Builder toBuilder();
@AutoValue.BuilderView on GitHub (pinned to 12126d8942)