Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not able to get query results using Room persistence

I am developing an Android app using the Room persistence library. I have a User and a Car entity

@Entity(tableName = "users")
public class User {

    @PrimaryKey
    @NonNull
    private int id;
    private String name;

    public User(@NonNull int id, String name) {
        this.id = id;
        this.name = name;
    }
}

and

@Entity(tableName = "cars", foreignKeys = @ForeignKey(parentColumns  = 
"id", childColumns = "userId", entity = User.class))
public class Car {

    @PrimaryKey(autoGenerate = true)
    private int id;
    private int userId;
    private String brand;

    public Car(int userId, String brand) {
        this.userId = userId;
        this.brand = brand;
    }
}

Also I have created a UserWithCar class as below:

public class UserWithCar {

    @Embedded(prefix = "user_")
    public User user;

    @Embedded(prefix = "car_")
    public Car car;
}

As you can see in the UserWithCar I use a prefix cause if I don't I get the following error:

Multiple fields have the same columnName: id. Field names: user > id, car > id.

I want to get all the UserWithCar using the following query:

@Query("SELECT * FROM users JOIN cars ON users.id = cars.userId")
List<UserWithCar> getUserWithCar();

Using this query I get the following error:

The query returns some columns [id, name, id, userId, brand] which are not use by com.roomdemo.data.models.UserWithCar. You can use @ColumnInfo annotation on the fields to specify the mapping. com.roomdemo.data.models.UserWithCar has some fields [user_id, user_name, car_id, car_userId, car_brand] which are not returned by the query. If they are not supposed to be read from the result, you can mark them with @Ignore annotation. You can suppress this warning by annotating the method with @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH). Columns returned by the query: id, name, id, userId, brand. Fields in com.foodtec.roomdemo.data.models.UserWithCar: user_id, user_name, car_id, car_userId, car_brand.

Can I have some help? Thanks!

Update Using @Wizard help, I removed the prefix from the @Embeded and I added @ColumnInfo "uId" for the User's id and "cId for the Car's id in order to not have the same id field. By this way it works!

like image 481
eliamyro Avatar asked Jan 31 '18 07:01

eliamyro


People also ask

What does room return if a query had no results?

If nothing is found based on your criteria, it will return null.

Why are you not allowed to access a room database on the main thread?

java. lang. IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. The developers who created Room block Room usage on the main application thread, as that is an anti-pattern.

How do you indicate that a class represents an entity to store in a room database?

Annotate the class with @Entity . Annotate the class with @Database . Make the class extend RoomEntity and also annotate the class with @Room . The DAO (data access object) is an interface that Room uses to map Kotlin functions to database queries.


1 Answers

Columns returned by the query: id, name, id, userId, brand. Fields in com.foodtec.roomdemo.data.models.UserWithCar: user_id, user_name, car_id, car_userId, car_brand.

Error indicates that, columns returned by query is different from Pojo class. It should be the same. Alternatively you can map your Pojo variable to column name using @ColumnInfo annotation.

For example,

@PrimaryKey
@NonNull
@ColumnInfo(name = "user_id")
private int id;

This way, id will be mapped to user_id.

like image 135
Paresh P. Avatar answered Nov 15 '22 16:11

Paresh P.