Cómo hacer que la clave principal sea un incremento automático para la librería Room Persistence

7 minutos de lectura

avatar de usuario
Sachin Chandil

Estoy creando una Entidad (Biblioteca de persistencia de salas) clase Comida, donde quiero hacer foodId como autoincremento.

@Entity
class Food(var foodName: String, var foodDesc: String, var protein: Double, var carbs: Double, var fat: Double)
{
    @PrimaryKey
    var foodId: Int = 0
    var calories: Double = 0.toDouble()
}

¿Cómo puedo configurar foodId un campo de autoincremento?

  • En vez de 0.toDouble() puedes usar 0.0 declararlo como un doble

    – RobCo

    22 mayo 2017 a las 15:57

  • ¿Cómo creas una nueva instancia de la clase Food? ¿Especificas manualmente el ID o lo dejas en blanco?

    – Zookey

    24 de junio de 2017 a las 8:52

  • Una nota para futuros lectores: la clave principal debe ser 0 para que Room la trate como no configurada. Si usa cualquier otro valor predeterminado (por ejemplo, -1), Room no generará automáticamente la identificación.

    – Martín Melka

    5 de abril de 2020 a las 12:44

avatar de usuario
MatPag

Necesitas usar el autoGenerate propiedad

Su anotación de clave principal debería ser así:

@PrimaryKey(autoGenerate = true)

Referencia para Clave primaria.

  • Gracias, estaba buscando autoIncrement, por eso no pude encontrarlo.

    -Sachin Chandil

    22 de mayo de 2017 a las 9:59

  • Hola, @MatPag, ¿qué sucede si quiero dos claves principales en una tabla (claves principales compuestas) y una de las claves principales debe incrementarse automáticamente? ¿Cómo puedo lograr eso? ¿Puedes responder esto aquí?

    –Priyanka Alachiya

    18 de octubre de 2017 a las 5:25

  • @MatPeg ¿Qué pasa si quiero tener una clave primaria que se genere automáticamente y una que provenga de REST? @Entity( primaryKeys = arrayOf(COLUMN_ID_LOCAL,COLUMN_ID_REMOTE)) ?

    – murcia

    18 de enero de 2018 a las 15:08

  • @murt Necesita una clave principal compuesta, pero no puede hacer lo que quiere lograr. Leer aquí

    – MatPag

    18 de enero de 2018 a las 15:20


  • Parte importante de la documentación vinculada: Insert methods treat 0 as not-set while inserting the item.

    – micha

    2 de marzo de 2020 a las 13:41

avatar de usuario
allan veloso

Puedes añadir @PrimaryKey(autoGenerate = true) como esto:

@Entity
data class Food(
        var foodName: String, 
        var foodDesc: String, 
        var protein: Double, 
        var carbs: Double, 
        var fat: Double
){
    @PrimaryKey(autoGenerate = true)
    var foodId: Int = 0 // or foodId: Int? = null
    var calories: Double = 0.toDouble()
}

  • foodId no necesita ser nulo (pero puede serlo). También se podrían usar valores predeterminados, por ejemplo. var foodId: Int = 0 y el autogenerado funcionaría correctamente.

    – Michael Baran

    1 de marzo de 2018 a las 12:15


  • @MichałBaran, del documento java, cuando el tipo es un java primitivo int o long, 0 se trata como anulable, cuando el tipo es Integer o Long, null es anulable. Dado que Kotlin Int cuando no anulable funciona en JVM como int primitivo, entonces tiene razón y var foodId: Int = 0 funcionará, pero var foodId: Int? = 0 no funcionará desde Int? se convierte en JVM como Integer. @JMK, si lo convierte en 0, TIENE que hacer un no anulable int por el motivo antes mencionado.

    – Alan Veloso

    12 de agosto de 2018 a las 21:41


  • Puedes escribir sin de otra manera: val jack = User(name = "Jack", phone= 1) En este caso, puede eliminar 0 del constructor.

    – Roman Soviak

    16 de noviembre de 2018 a las 10:13

  • El problema que veo con este enfoque es que se trata de una clase de datos. Cuando Food es una clase de datos (como en el fragmento), food se usa para la comparación equals(), por lo que dos alimentos con diferentes foodId pueden considerarse iguales. El uso de argumentos con nombre con valores predeterminados resolverá el problema.

    – Sotti

    1 de febrero de 2019 a las 7:31


  • @ neer17 dado que RoomId generará automáticamente el ID de comida en la inserción, lo más probable es que no sirva de nada tenerlo en el constructor.

    – Alan Veloso

    28 oct 2019 a las 13:32

avatar de usuario
kunal khedkar

agregar @PrimaryKey(autoGenerate = true)

@Entity
public class User {

    @PrimaryKey(autoGenerate = true)
    private int id;

    @ColumnInfo(name = "full_name")
    private String name;

    @ColumnInfo(name = "phone")
    private String phone;

    public User(){
    }

    //type-1
    public User(String name, String phone) {
        this.name = name;
        this.phone = phone;
    }

    //type-2
    public User(int id, String name, String phone) {
        this.id = id;
        this.name = name;
        this.phone = phone;
    }

}

mientras almacena datos

 //type-1
 db.userDao().InsertAll(new User(sName,sPhone)); 

 //type-2
 db.userDao().InsertAll(new User(0,sName,sPhone)); 

tipo 1

Si no está pasando valor para la clave principal, de forma predeterminada será 0 o nulo.

tipo 2

Poner nulo o cero para la identificación al crear un objeto (mi objeto de usuario de caso)

Si el tipo de campo es largo o int (o su TypeConverter lo convierte en largo o int), los métodos de inserción tratan 0 como no establecido al insertar el elemento.

Si el tipo de campo es Integer o Long (Object) (o su TypeConverter lo convierte en Integer o Long), los métodos de inserción tratan nulo como no establecido al insertar el elemento.

  • ¿Podemos pasar una identificación personalizada a la Entidad, aunque esté configurada para generar automáticamente?

    – Igor Ganapolski

    11 mayo 2018 a las 20:00

  • @Igor Ganapolsky Sí, pero la entrada se generará con esa identificación personalizada [ auto-increment will not work ] Y si vuelve a pasar la misma identificación, arrojará la excepción ‘Falló la restricción ÚNICA’, por lo que debe pasar siempre una nueva identificación o hacerlo [0 or null] y deje que el incremento automático haga este trabajo por usted.

    – kunal khedkar

    14 de mayo de 2018 a las 4:24


  • ¿Por qué incluso permite que el usuario coloque la identificación en el constructor si desea generar automáticamente?

    – infierno

    18 mayo 2018 a las 15:48


  • En Kotlin puedes usar la clase de datos y escribir: val jack = User(name = "Jack", phone= 1) En este caso, puede eliminar 0 del constructor.

    – Roman Soviak

    16 de noviembre de 2018 a las 10:09


  • @hellcast Si no incluye la identificación en el constructor (como acabo de aprender por las malas) cuando consulta la base de datos, no asignará el campo de identificación (será lo que sea que lo inicialice en el constructor) ya que Supongo que llama al mismo constructor al completar los campos del objeto.

    -Ali Hirani

    16 de mayo de 2019 a las 9:07


avatar de usuario
Renetik

Es increíble después de tantas respuestas, pero al final lo hice un poco diferente. No me gusta que la clave principal sea anulable, quiero tenerla como primer argumento y también quiero insertarla sin definirla y tampoco debería ser var.

@Entity(tableName = "employments")
data class Employment(
    @PrimaryKey(autoGenerate = true) val id: Long,
    @ColumnInfo(name = "code") val code: String,
    @ColumnInfo(name = "title") val name: String
){
    constructor(code: String, name: String) : this(0, code, name)
}

Esto funciona para mí:

@Entity(tableName = "note_table")
data class Note(
    @ColumnInfo(name="title") var title: String,
    @ColumnInfo(name="description") var description: String = "",
    @ColumnInfo(name="priority") var priority: Int,
    @PrimaryKey(autoGenerate = true) var id: Int = 0//last so that we don't have to pass an ID value or named arguments
)

Tenga en cuenta que la identificación es la última para evitar tener que usar argumentos con nombre al crear la entidad, antes de insertarla en Room. Una vez que se haya agregado a la sala, use la identificación al actualizar la entidad.

avatar de usuario
Om Prakash Sharma

@Entity(tableName = "user")
data class User(

@PrimaryKey(autoGenerate = true)  var id: Int?,
       var name: String,
       var dob: String,
       var address: String,
       var gender: String
)
{
    constructor():this(null,
        "","","","")
}

avatar de usuario
Nicola Gallazzi

Por ejemplo, si tienes un users entidad que desea almacenar, con campos (firstname, lastname , email) y quieres una identificación autogenerada, haz esto.

@Entity(tableName = "users")
data class Users(
   @PrimaryKey(autoGenerate = true)
   val id: Long,
   val firstname: String,
   val lastname: String,
   val email: String
)

A continuación, Room generará e incrementará automáticamente el id campo.

  • Cada vez que creamos un nuevo objeto Usuarios, necesitaremos pasar un campo de identificación. ¿Se puede evitar esto?

    – Aditya Ladwa

    14 de septiembre de 2017 a las 6:39


  • si, poner @PrimaryKey(autoGenerated = true) val id: Long? = null fuera del constructor, en el cuerpo de la clase

    – Alan Veloso

    15 de octubre de 2017 a las 9:56

  • @Magritte Care para elaborar más pls?

    – Ispam

    27 de junio de 2018 a las 0:40

  • @Ispam En mi respuesta anterior, publiqué cómo debería verse la clase completa.

    – Alan Veloso

    27 de junio de 2018 a las 5:22

  • En realidad, simplemente puede poner 0 como ID. Room generará automáticamente una identificación si ha configurado la opción @PrimaryKey.

    – romaneso

    11 de marzo de 2019 a las 23:20

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad