Después de unos meses trabajando con Room en Android nos hemos encontrado con algunos inconvenientes que nos han dificultado realmente el desarrollo respecto a otros ORM del mercado (como Hibernate). Algunos de los problemas encontrados son los siguientes:

  • No permite queries de inserción manuales, sólo puedes anotar métodos con @Insert y definir la estrategia de reemplazo en caso de que haya conflictos.
  • No permite definir Foreign Keys como colecciones dentro de una entidad. Por ejemplo, si tenemos una entidad Album, no podemos definir una Listz<Track> como Foreign Key dentro de la misma, si no que nos fuerza a meter en la entidad track Track un campo albumId anotado como Foreign Key. Esto hace que las inserciones en la tabla Album no sean atómicas ya que tienes que insertar en dos tablas por separado (tampoco permite queries de inserción custom como se ve en el primer punto).
  • No permite definir el tipo de retorno en las inserciones. Es decir, si queremos insertar en una tabla cuya Primary Key está definida como String, el método de inserción siempre nos devolverá Long (o List<Long> en caso de que insertemos varios elementos), siendo este Long el rowId.
  • Al no permitir listas de Foreign Keys en las entidades, para lectura tenemos que crearnos una vista (en forma de una data class) donde incluyamos las relaciones de la entidad que queremos leer, de forma que tenemos duplicados los modelos de la base de datos por cada lectura de la misma entidad que hagamos. Supongamos que tenemos una entidad Featured que tiene únicamente un ID
@Entity(tableName = FeaturedDb.FEATURED_TABLE_NAME)
data class FeaturedEntity(
 @PrimaryKey @ColumnInfo(name = FeaturedDb.FEATURED_ID_FIELD_NAME) var id: String
)

 

GSAS speakers 2019

Y luego tenemos N entidades que hacen referencia a este Featured a través de una Foreign Key (en este caso será sólo album):

data class AlbumEntity(
 @PrimaryKey @ColumnInfo(name = AlbumDb.ALBUM_ID_FIELD_NAME) var id: String,
 var title: String,
 @ColumnInfo(name = AlbumDb.FEATURED_ID_KEY_FK) var featuredId: String? = null
)

Si queremos leer un FeaturedEntity por ID en una sola query, tendremos que tener un modelo intermedio tal que:

data class FeaturedDbDto(
 @Embedded var featuredEntity: FeaturedEntity,
 @Relation(
     entity = AlbumEntity::class,
     parentColumn = "id",
     entityColumn = "featuredId"
 ) var albums: List = emptyList()
)

Estas son sólo algunas de las dificultades con las que nos hemos encontrado, aunque sin duda hay muchas otras, lo que nos hará replantearnos el uso de Room en Android en futuros proyectos.

Apium Academy

Aun así no todo es malo. Room en Android también nos aporta herramientas que hacen nos hacen la vida más sencilla.

  • El uso intensivo de anotaciones hace que no tengamos que escribir apenas código para interactuar con la base de datos. Esto es algo que, por ejemplo, se echa de menos cuando se trabaja con Realm.
  • Room en Android nos proporciona integración con LiveData y RxJava out of the box, lo que nos facilita mucho crear aplicaciones reactivas sin tener que lidiar con la creación de los Observables nosotros mismos, lo que nos permite observar cambios en la base de datos para reaccionar en el momento en que se actualice la misma.