Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Room library - select all fields for embedded entities

I have two entities with a foreign key relation: product and category.

@Entity(primaryKeys = "id")
public class Product {
    public final long id;

    @NonNull
    public final String name;

    @ForeignKey(entity = Category.class, parentColumns = "id", childColumns = "categoryId")
    public final long categoryId;

    public Product(long id, @NonNull String name, long categoryId) {
        this.id = id;
        this.name = name;
        this.categoryId = categoryId;
    }
}

@Entity(primaryKeys = "id")
public class Category {
    public final long id;

    @NonNull
    public final String name;

    public Category(long id, @NonNull String name) {
        this.id = id;
        this.name = name;        
    }
}

I want to select all fields for both entities. I've defined a separate entity for it, with @Embedded annotation:

public class ProductWithCategory {
    @NonNull
    @Embedded(prefix = "product_")
    public final Product product;

    @NonNull
    @Embedded(prefix = "category_")
    public final Category category;

    public ProductWithCategory(@NonNull Product product, @NonNull Category category) {
        this.product = product;
        this.category = category;
    }
}

Now I can create a query like this:

@Query("SELECT product.id as product_id, product.name as product_name, product.categoryId as product_categoryId, category.id as category_id, category.name as category_name FROM product JOIN category on categoryId = category.id WHERE product.id = :id")
LiveData<ProductWithCategory> getProduct(long id);

The problem is that I have to manually specify all fields which becomes too verbose if I have entities with 5 - 10 fields. Is it possible to use some wildcard approach without manually specifying all fields?

like image 784
Random Avatar asked Jan 03 '18 13:01

Random


People also ask

What is the difference between SQLite and room database?

Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. In case of SQLite, There is no compile time verification of raw SQLite queries. But in Room there is SQL validation at compile time.

What is embedded in room database?

room. Embedded instead. Can be used as an annotation on a field of an Entity or Pojo to signal that nested fields (i.e. fields of the annotated field's class) can be referenced directly in the SQL queries. If the container is an Entity , these sub fields will be columns in the Entity 's database table.

What are the entities in room?

A Room entity includes fields for each column in the corresponding table in the database, including one or more columns that comprise the primary key.


1 Answers

Finally I used @Relation annotation to solve this. The only disadvantage is that I have to use either List or Set for it, even if in this case it's either 0 or 1 entity:

public class ProductWithCategory {
    @NonNull
    @Embedded
    public final Product product;

    @Relation(parentColumn = "categoryId", entityColumn = "id", entity = Category.class)
    public List<Category> category;

    public ProductWithCategory(@NonNull Product product) {
        this.product = product;
    }
}

But that simplifies the query:

@Query("SELECT * FROM product WHERE product.id = :id")
LiveData<ProductWithCategory> getProduct(long id);
like image 107
Random Avatar answered Nov 10 '22 08:11

Random