0

I have these relationships:

Customer > Address

Customer > Property

Property > Address

So I'm trying to do this:

data class DetailedCustomerInformation(
    @Embedded
    val customer: Customer,

    @Relation(parentColumn = "addressId", entityColumn = "id")
    val address: Address,

    @Relation(parentColumn = "propertyId", entityColumn = "id")
    val property: PropertyWithAddress
) : Serializable

Where PropertyWithAddress is

data class PropertyWithAddress(
    @Embedded
    var property: Property,

    @Relation(parentColumn = "addressId", entityColumn = "id")
    var address: Address
)

But it doesn't work because PropertyWithAddress isn't a database Entity/View.

My question is wheater it's possible to map these relationships using some room mechanism. I know that I can do the queries directly and load the objects, but I would like to know if room supports this in any way.

1 Answers1

0

It is possible to map this scenario on room directly?

Yes, and you were very close to the solution.

But it doesn't work because PropertyWithAddress isn't a database Entity/View.

You need to specify the table/entity of the parent from which the POJO is to be extracted (Property) in the @Relation using the entity= parameter. (i.e. an entity is expected and PropertyWithAddress is not an entity)

e.g.

data class DetailedCustomerInformation(
    @Embedded
    val customer: Customer,
    @Relation(entity = Address::class,parentColumn = "addressId", entityColumn = "id")
    val address: Address,
    @Relation(entity = Property::class, parentColumn = "propertyId",entityColumn = "id")
    val propertyWithAddress: PropertyWithAddress
)
  • Note that I always code the entity = parameter even if not required

So using the above and approximations of you other Entities and the @Dao class :-

@Dao
abstract class CustomerDao {

    @Insert
    abstract fun insert(customer: Customer): Long
    @Insert
    abstract fun insert(address: Address): Long
    @Insert
    abstract fun insert(property: Property): Long
    @Query("SELECT * FROM customer")
    abstract fun getDetailedCustomerInformation(): List<DetailedCustomerInformation>
}

and then using the following in an Activity (run on the main thread for convenience and brevity) :-

    db = TheDatabase.getInstance(this)
    customerDao = db.getCustomerDao()

    var a1 = customerDao.insert(Address(addressDetails = "This is address 1"))
    var a2 = customerDao.insert(Address(addressDetails = "This is address 2"))
    var a3 = customerDao.insert(Address(addressDetails = "This is address 3"))
    var p1 = customerDao.insert(Property(addressId = a1,propertyDetails = "This is property1"))
    var p2 = customerDao.insert(Property(addressId = a2,propertyDetails = "This is property 2"))
    customerDao.insert(Customer(addressId = a3,propertyId = p1,customerDetails =  "This is customer 1"))
    customerDao.insert(Customer(addressId = a1,propertyId = p2,customerDetails = "This is customer 2"))
    var TAG = "CUSTINFO"
    for(dci: DetailedCustomerInformation in customerDao.getDetailedCustomerInformation()) {
        Log.d("CUSTINFO","Customer Details = ${dci.customer.customerDetails}" +
                "\n\tCustomer's address is ${dci.address.addressDetails}" +
                "\n\tProperty is ${dci.propertyWithAddress.property.propertyDetails} address is ${dci.propertyWithAddress.address.addressDetails}"
        )
    }

The result output to the log is :-

D/CUSTINFO: Customer Details = This is customer 1
        Customer's address is This is address 3
        Property is This is property1 address is This is address 1
D/CUSTINFO: Customer Details = This is customer 2
        Customer's address is This is address 1
        Property is This is property 2 address is This is address 2
MikeT
  • 51,415
  • 16
  • 49
  • 68