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

在Kotlin中为Room的@Entity数据类配置@ForeignKey与主键

How to Configure Room @Entity, Primary Key, and Foreign Key for Your Kotlin Data Class

Got it, let's walk through how to properly set up Room's annotations for your Foo data class—including primary keys, foreign keys, and keeping your Parcelable setup intact.

1. Basic @Entity Annotation Setup

First, add the @Entity annotation to your class. In Kotlin, we use square brackets [] for arrays (like the foreignKeys parameter) instead of curly braces, which is a key difference from Java-style Room code.

2. Primary Key Configuration

You have two options for defining a primary key:

  • Single-field primary key: Add @PrimaryKey directly to the field you want to use as the unique identifier. If you need an auto-incrementing numeric key, add autoGenerate = true to the annotation.
  • Composite primary key: Define multiple fields as the primary key using the primaryKeys property in @Entity (useful if no single field is unique on its own).

3. Foreign Key Configuration

To add a foreign key, you'll need to:

  • Add a field to Foo that maps to the primary key of the parent entity (e.g., userId for a User entity).
  • Define the ForeignKey inside the foreignKeys array of @Entity, specifying the parent entity, matching parent/child columns, and delete/update behavior.

Full Example Code

Here's a complete implementation that ties it all together. Let's assume we're using stringOne as the primary key and adding a foreign key to a User entity:

import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey

@Parcel(Parcel.Serialization.BEAN)
@Entity(
    foreignKeys = [
        ForeignKey(
            entity = User::class,
            parentColumns = ["id"], // Must match the primary key field name in your User entity
            childColumns = ["userId"], // The field in Foo that links to User's id
            onDelete = ForeignKey.CASCADE // Adjust behavior as needed (e.g., SET_NULL, RESTRICT)
        )
    ]
)
data class Foo @ParcelConstructor constructor(
    @PrimaryKey val stringOne: String, // Single-field primary key
    var stringTwo: String,
    var stringThree: String,
    var userId: Long // New field to hold the foreign key reference to User
) : BaseFoo() {
    // If Room runs into instantiation issues (rare with modern Room/Kotlin), add a no-arg constructor:
    // constructor() : this("", "", "", 0L)
}

// Ensure your parent User entity is properly annotated too:
@Entity
data class User(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val username: String
)

Key Notes

  • Foreign Key Matching: The userId field in Foo must match the data type of User's primary key (e.g., Long if User.id is a Long).
  • Parcelable Compatibility: Your existing @ParcelConstructor setup should work seamlessly with Room. If you encounter issues, adding a no-arg constructor (like the commented one above) can resolve instantiation problems.
  • Composite Primary Key Example: If you need a composite key, replace the field-level @PrimaryKey with:
    @Entity(
        primaryKeys = ["stringOne", "stringTwo"],
        foreignKeys = [...]
    )
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:49:25