Fixed
Status Update
Comments
da...@google.com <da...@google.com> #2
Thanks for reporting this, the issue is that the way we query relations is by storing all the parent keys in a Map and then using a 'WHERE IN' clause. By using a relationship key of type BLOB we end up using a byte[] as the key of the map and sadly the primitive type byte[] uses object identity for equals and hashCode, thus even the query result is probably fine, Room fails to find the correct parent key in the Map to associate the child.
I'll try to fix this, in the meantime you can avoid this by storing your UUID as a TEXT column (a String field) instead of a BLOB.
I'll try to fix this, in the meantime you can avoid this by storing your UUID as a TEXT column (a String field) instead of a BLOB.
ap...@google.com <ap...@google.com> #3
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 9ae79b1871c73e9e318d4a9c5e957d3b33fcc4c3
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Fri Jul 19 15:48:11 2019
Use ByteBuffer when a relation's key column is of type BLOB.
Relationship resolution via @Relation is done through a Map and when
the key column is of type BLOB a ByteBuffer has to be used, otherwise
using a byte[] would always cause the lookup to fail due to byte[]
using object identity as equals and hashCode.
This CL makes it so that the only during key manipulation and binding
a ByteBuffer is used, which simply wraps the byte[] data of the BLOB
and implements Comparable.
Bug: 137881998
Test: testapp:cC
Change-Id: Iad5d54573b60671467d7e6daa4fbfb52cfa8e8b3
M room/compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
A room/compiler/src/main/kotlin/androidx/room/solver/types/ByteBufferColumnTypeAdapter.kt
M room/compiler/src/main/kotlin/androidx/room/vo/RelationCollector.kt
M room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/TestDatabase.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/dao/RobotsDao.java
M room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/dao/UserDao.java
M room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/PojoWithRelationTest.java
M room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/TestDatabaseTest.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/Cluster.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/Hivemind.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/NameAndUsers.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/Robot.java
https://android-review.googlesource.com/1087497
https://goto.google.com/android-sha1/9ae79b1871c73e9e318d4a9c5e957d3b33fcc4c3
Branch: androidx-master-dev
commit 9ae79b1871c73e9e318d4a9c5e957d3b33fcc4c3
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Fri Jul 19 15:48:11 2019
Use ByteBuffer when a relation's key column is of type BLOB.
Relationship resolution via @Relation is done through a Map and when
the key column is of type BLOB a ByteBuffer has to be used, otherwise
using a byte[] would always cause the lookup to fail due to byte[]
using object identity as equals and hashCode.
This CL makes it so that the only during key manipulation and binding
a ByteBuffer is used, which simply wraps the byte[] data of the BLOB
and implements Comparable.
Bug: 137881998
Test: testapp:cC
Change-Id: Iad5d54573b60671467d7e6daa4fbfb52cfa8e8b3
M room/compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
A room/compiler/src/main/kotlin/androidx/room/solver/types/ByteBufferColumnTypeAdapter.kt
M room/compiler/src/main/kotlin/androidx/room/vo/RelationCollector.kt
M room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/TestDatabase.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/dao/RobotsDao.java
M room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/dao/UserDao.java
M room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/PojoWithRelationTest.java
M room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/TestDatabaseTest.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/Cluster.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/Hivemind.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/NameAndUsers.java
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/Robot.java
da...@google.com <da...@google.com> #4
A fix for this issue will be available in Room 2.2.0-alpha02
Description
Version used: 2.1.0
Devices/Android versions reproduced on: any device/version
When I define UUID as ids for my POJOs, and try to use @Relation, as result relation list is always empty.
Here is example:
object RoomTypeConverters {
@TypeConverter
@JvmStatic
fun uuidToData(uuid: UUID?): ByteArray = ...
@TypeConverter
@JvmStatic
fun dataToUUID(data: ByteArray?): UUID = ...
}
@Entity
data class Pet(
@ PrimaryKey
val uuid: UUID,
val userUuid: UUID,
val name: String
// other fields
)
data class UserNameAndAllPets(
val uuid: UUID,
val name: String,
@Relation(parentColumn = "uuid", entityColumn = "userUuid")
lateinit var pets: List<Pet>
)
@Dao
interface UserPetDao {
@Query("SELECT id, name from User")
fun loadUserAndPets(): List<UserNameAndAllPets>
}