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

使用Retrofit2获取数据存入Room数据库时插入User失败求助

Troubleshooting Room Insertion Failure After Retrofit Fetch

Hey there! Let's break down why your User data isn't making it into the Room database—it's a common mapping issue, easy to fix once you spot it.

Root Cause

Looking at your code and the server's JSON response, here's the critical mismatch:

  • Your User entity uses @SerializedName("_id") for the primary key field _id
  • But the server returns the user ID under the key "id" (no leading underscore)

Since Gson can't map "id" from the JSON to your _id field (it's looking for "_id" instead), the _id value in your parsed User objects ends up being null. And because you marked _id with @NonNull as the primary key, Room rejects any insertion where the primary key is null—this is exactly why your inserts are failing.

Fix Steps

1. Correct the Serialization Mapping

Update the @SerializedName annotation on your _id field to match the server's JSON key:

@Entity(tableName = "Users")
public class User {
    @NonNull
    @PrimaryKey
    @SerializedName("id") // Changed from "_id" to "id"
    private String _id;
    @ColumnInfo(name = "name")
    @SerializedName("name")
    @Expose
    private String name;
    @ColumnInfo(name = "age")
    @SerializedName("age")
    @Expose
    private String age;
    
    // Constructors, getters, setters remain the same
}

2. Verify Parsed Objects

Before inserting into Room, add a quick log or debug check to confirm that the _id field of each parsed User is now populated with the correct value from the server:

// After fetching data via Retrofit
List<User> users = response.body();
for (User user : users) {
    Log.d("UserDebug", "User ID: " + user.get_id()); // Should show non-null IDs now
}

3. Handle Database Migration (If Needed)

If you've already run the app with the old entity structure, you'll need to update your Room database version to avoid migration errors. In your RoomDatabase subclass:

@Database(entities = {User.class}, version = 2) // Increment version number
public abstract class AppDatabase extends RoomDatabase {
    // DAO definitions
}

(For testing, you can use fallbackToDestructiveMigration() during database building, but avoid this in production as it will wipe existing data.)

Optional: Flexible Mapping (For Edge Cases)

If you ever need to support both "id" and "_id" as JSON keys (for backward compatibility), you can use the alternate parameter in @SerializedName:

@SerializedName(value = "id", alternate = "_id")
private String _id;

But for your current use case, just changing the value to "id" is the cleanest solution.


内容的提问来源于stack exchange,提问作者Digvijay Singh Thakur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:31:52