-
-
Notifications
You must be signed in to change notification settings - Fork 150
Description
What happened?
The following code
QueryJobConfiguration queryJobConfiguration = QueryJobConfiguration
.newBuilder("SELECT * FROM dataset.table")
.build()
JobId jobId = JobId.newBuilder().setProject(project).setRandomJob().build()
Job job = bigQuery.create(JobInfo.newBuilder(queryJobConfiguration)
.setJobId(jobId)
.build())
TableResult tableResult = job.getQueryResults()fails with
Cannot invoke "com.google.cloud.bigquery.TableId.getProject()" because "tableId" is null
java.lang.NullPointerException: Cannot invoke "com.google.cloud.bigquery.TableId.getProject()" because "tableId" is null
at com.google.cloud.bigquery.BigQueryImpl.listTableData(BigQueryImpl.java:1704)
at com.google.cloud.bigquery.BigQueryImpl.listTableData(BigQueryImpl.java:1671)
at com.google.cloud.bigquery.Job.getQueryResults(Job.java:429)
See https://github.com/pavelfomin/spring-boot-bq-example/blob/main/src/test/groovy/com/droidablebee/springboot/bq/service/BigQueryServiceISpec.groovy. The first scenario fails when destinationTable is not set (works with real BigQuery). The second scenario sets the destinationTable explicitly as a workaround.
What did you expect to happen?
In real BigQuery:
When I run a query, BigQuery creates a temporary destination table to store the results.
Job.getQueryResults() fetches rows from this temporary table, regardless of the original table schema.
It also sets QueryJobConfiguration.destinationTable with the reference to that temporary table.
Why it works:
BigQuery dynamically creates the destination table schema based on the query output, not the source table.
The client library fetches results from this destination table, which matches the query output.
Why the emulator fails:
The emulator does not fully implement this behavior. It may not create a destination table with the correct schema, or may not set the destinationTable field in the job metadata.
The Java client expects this metadata to be present and correct, so it can fetch results from the temporary table.
If the schema doesn’t match, or the destination table is missing, you get errors (like NullPointerException).
How can we reproduce it (as minimally and precisely as possible)?
git clone [email protected]:pavelfomin/spring-boot-bq-example.git
./gradlew clean buildAnything else we need to know?
No response