[英]ClassCastException when reading nested list of records
我正在讀取來自 Dataflow 的 BigQuery 表,其中一個字段是“記錄”和“重復”字段。 所以我希望 Java 中的結果數據類型是List<TableRow>
。
但是,當我嘗試遍歷列表時,出現以下異常:
java.lang.ClassCastException: java.util.LinkedHashMap 無法轉換為 com.google.api.services.bigquery.model.TableRow
表架構看起來像這樣:
{
"id": "my_id",
"values": [
{
"nested_record": "nested"
}
]
}
迭代值的代碼如下所示:
String id = (String) row.get("id");
List<TableRow> values = (List<TableRow>) row.get("values");
for (TableRow nested : values) {
// more logic
}
異常在循環開始的地方拋出。 這里明顯的解決方法是將值轉換為LinkedHashMaps
列表,但感覺不對。
為什么 Dataflow 會為嵌套的“記錄”拋出這種錯誤?
當我嘗試使用谷歌雲數據流從 BigQuery 讀取嵌套表時,我遇到了同樣的ClassCastException
。 最后通過將TableRow
轉換為不同的數據結構來解決,具體取決於我使用的 DataFlow 運行程序:
DirectRunner
:投射到LinkedHashMap
DataflowRunner
:轉換為TableRow
。例子:
Object valuesList = row.get("values");
// DirectRunner
for (TableRow v : (List<LinkedHashMap>) valuesList) {
String name = v.get("name");
String age = v.get("age");
}
// DataflowRunner
for (TableRow v : (List<TableRow>) valuesList) {
String name = v.get("name");
String age = v.get("age");
}
其根本原因是 DirectRunner 在步驟之間執行的編碼往返,這通常不會在 Dataflow 中執行。 作為 Map 字段訪問重復記錄(或任何記錄)將在這兩個運行器上成功執行,因為 TableRow 實現了 Map 接口。 記錄被讀取為“TableRow”類型,但是當它們被編碼時,它們被編碼為一個簡單的 JSON 映射。 由於 JSON 編碼器無法識別地圖字段的類型,因此它將記錄反序列化為簡單的地圖類型。
TableRow 是一個 Map,因此您可以將這兩種情況都視為 Map:
String id = (String) row.get("id");
List<? extends Map> values = row.get("values");
for (Map nested : values) {
// more logic
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.