You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Realm主键约束异常求助:已存在值1/2,常规方案无效

Primary Key Constraint Broken with Value 1/2 in Realm (Even After Clear/CreateOrUpdate)

Let's break down what's happening here and fix this issue step by step:

The Root Cause: Mismatched Primary Key Types

Looking at your code and JSON data, there's a critical mismatch you might have missed:

  • Your StationRealm class defines the primary key id as a String type
  • But your JSON data provides id as a numeric value (e.g., 1, 2)

Realm handles type conversions silently here, but this creates a hidden problem: when parsing the JSON, Realm stores the numeric id as a numeric type (like Long) instead of a String. This leads to two major issues:

  1. When you call realm.clear(StationRealm.class), it might not properly delete entries where the primary key is stored as a numeric type (since your entity class declares it as String).
  2. createOrUpdateAllFromJson() can't match the numeric id from JSON to the existing (numeric-stored) primary keys in the database, so it tries to insert a new entry instead of updating—triggering the duplicate key error.

Fixes to Try

1. Align Primary Key Types (Most Critical)

You have two options to fix the type mismatch:

Option A: Change Entity Class's id to Numeric Type

Update your StationRealm class to use a numeric primary key that matches the JSON data:

@PrimaryKey
private int id; // Or long if your IDs can be larger than int's limit

This is the simplest fix since your JSON already uses numeric IDs. With this change:

  • createOrUpdateAllFromJson() will correctly recognize matching primary keys and update existing entries instead of inserting duplicates.
  • realm.clear(StationRealm.class) will properly delete all entries in the table.

Option B: Modify JSON to Use String IDs

If you need to keep the id as a String in your entity class, adjust your JSON data to wrap IDs in quotes:

[{"id":"1","name":"1 - Allen Street", ...}, {"id":"2", ...}]

This ensures Realm parses the id as a String, matching your entity class's definition.

2. Verify Clear/Transaction Logic

Make sure your clear operation runs inside a valid transaction (which your commented code does). Uncomment that line and add a quick check to confirm the table is actually being cleared:

if (null != realm) {
    try {
        realm.beginTransaction();
        realm.clear(StationRealm.class);
        // Add this log to confirm the table is empty
        long count = realm.where(StationRealm.class).count();
        Log.d(TAG, "After clear, StationRealm count: " + count);
        realm.createOrUpdateAllFromJson(StationRealm.class, json);
        realm.commitTransaction();
        sendStatusRefreshedMessage(context);
    } catch (Exception ex) {
        realm.cancelTransaction();
        Log.e(TAG, "RealmDBStations: " + ex.getMessage());
    }
}

If the count isn't 0 after clearing, you might be working with a different Realm instance or database file.

3. Clean Up Stale Database Data

If you've been testing with mismatched types, old data might be lingering in the Realm file. To rule this out:

  • Uninstall your app from the test device/emulator to delete the existing Realm database.
  • Rebuild and re-run your app with the fixed type alignment.

Why Your Previous Fixes Didn't Work

  • realm.clear(): Failed because it was targeting entries with String primary keys, but your existing data had numeric primary keys stored under the same table.
  • createOrUpdateAllFromJson(): Couldn't match the numeric JSON IDs to the stored numeric keys (since your entity class declared id as String, Realm didn't recognize them as matching primary keys).

内容的提问来源于stack exchange,提问作者Liru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:30:50