为什么我收到 Expo SQLite:在 NativeDatabase.execAsync 中出现带有 NullPointerException 的持久“未处理的承诺拒绝”?

问题描述 投票:0回答:1

我正在使用 Expo (SDK 51) 和 SQLite 开发 React Native 应用程序。我已经实现了本地数据库操作来管理订单,但我遇到了有关未处理的承诺拒绝的持续警告。详情如下:

问题

每次应用程序刷新时,我都会收到以下警告:

Possible unhandled promise rejection (id: X):
Error: Call to function 'NativeDatabase.execAsync' has been rejected.
-> Caused by: java.lang.NullPointerException: java.lang.NullPointerException

警告持续出现,并且 id 每次递增(例如 id: 1、id: 2、id: 3 等)。

我的代码

这是我的数据库操作的相关代码:

import * as SQLite from 'expo-sqlite';
import { useEffect } from 'react';

async function createLocalDatabase() {
  const db = await SQLite.openDatabaseAsync("orders.db");
  await db.execAsync(`
    PRAGMA journal_mode = WAL;
    CREATE TABLE IF NOT EXISTS order_header (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    firm TEXT NOT NULL,
    shop TEXT NOT NULL,
    delivery_date DATE NOT NULL,
    notice TEXT,
    counterparty_id INTEGER
    );

    CREATE TABLE IF NOT EXISTS order_items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    item_name TEXT NOT NULL,
    sale_unit TEXT NOT NULL,
    quantity REAL NOT NULL,
    order_header_id INTEGER NOT NULL,
    FOREIGN KEY (order_header_id) REFERENCES order_header (id)
    );
  `);
}

useEffect(() => {
  createLocalDatabase();
}, []);

async function insertOrderHeader(db, firm, shop, deliveryDate, notice, counterpartyId) {
  const statement = await db.prepareAsync(
    "INSERT INTO order_header (firm, shop, delivery_date, notice, counterparty_id) VALUES (?, ?, ?, ?, ?)"
  );

  try {
    const result = await statement.executeAsync([
      firm,
      shop,
      deliveryDate,
      notice,
      counterpartyId,
    ]);
    return result.lastInsertRowId;
  } finally {
    await statement.finalizeAsync();
  }
}

async function insertOrderItem(
  db,
  orderHeaderId,
  itemName,
  saleUnit,
  quantity
) {
  const statement = await db.prepareAsync(
    "INSERT INTO order_items (order_header_id, item_name, sale_unit, quantity) VALUES (?, ?, ?, ?)"
  );

  try {
    await statement.executeAsync([
      orderHeaderId,
      itemName,
      saleUnit,
      quantity,
    ]);
  } finally {
    await statement.finalizeAsync();
  }
}

async function insertOrderWithItems(
  firm,
  shop,
  deliveryDate,
  notice,
  orderItems
) {
  const db = await SQLite.openDatabaseAsync("orders.db");

  try {
    await db.execAsync("BEGIN TRANSACTION");

    const orderHeaderId = await insertOrderHeader(
      db,
      firm,
      shop,
      deliveryDate,
      notice
    );

    for (const item of orderItems) {
      await insertOrderItem(
        db,
        orderHeaderId,
        item.name,
        item.saleUnit,
        item.quantity
      );
    }

    await db.execAsync("COMMIT");

    console.log(
      "Order with items inserted successfully. Order ID:",
      orderHeaderId
    );

    return orderHeaderId;
  } catch (error) {
    await db.execAsync("ROLLBACK");
    console.error("Error inserting order with items:", error);
    throw error;
  }
}

我尝试过的

  1. 我已确保所有 SQLite 操作都包含在 try/catch 块中。
  2. 我对所有异步 SQLite 操作使用await。
  3. 我已经实现了插入带有商品的订单的事务处理。

问题

  1. 为什么我会收到这种持续的未处理承诺拒绝警告?
  2. 为什么警告的 ID 在每次应用刷新时都会增加?
  3. 如何正确处理或解决这个问题?
  4. 我初始化或使用数据库的方式有问题吗?

任何见解或建议将不胜感激。谢谢!

环境

展会版本:~51.0.18

expo-sqlite 版本:~14.0.5

React Native 版本:0.74.3

设备:摩托罗拉 E20

react-native sqlite expo
1个回答
0
投票

我使用同一部手机也遇到了同样的问题。这似乎是摩托罗拉及其处理 NativeDatabase 的错误,因为在 TCL 或三星等其他设备中,此问题不会重现。

修复方法是每次打开数据库时使用新连接

   const db = await SQLite.openDatabaseAsync(databaseFile, {
  useNewConnection: true
});

© www.soinside.com 2019 - 2024. All rights reserved.