Fixed
Status Update
Comments
da...@google.com <da...@google.com> #2
This is indeed a long standing issue in Room and will likely be more relevant with the map / multimap return type. I think we can show a warning to start but we'll also take a deeper look to see how we can solve the duplicate column name issue.
As a workaround you can always use a column alias and a POJO class with matching field name.
ap...@google.com <ap...@google.com> #3
Project: platform/frameworks/support
Branch: androidx-main
commit 894b0ff2c1b095a46803975f400a561eb974ea28
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Fri Oct 29 10:56:31 2021
Duplicate column resolution heuristic algorithm
AmbiguousColumnResolver contains an algorithm to map query result columns to data objects (POJOs) columns. We call data object columns 'mapping' and in a multimap query where there might be multiple data objects we refer to the list of all their columns 'mappings'. The algorithm uses a grouping / neighboring strategy to assign the duplicate columns to their right data objects matching their name along with taking into account the the nearby columns since in a star-projected query all columns coming from a table will appear in the result before the next table. Room will generate code that uses the algorithm at runtime if the query has a star-projection, if not then Room will use the algorithm during compile-time since the columns result order is known and fixed.
The algorithm does not solve all cases, specifically those where one of the data objects has a single column which is the duplicate column. For those situation Room will warn the user so that they alias the duplicate column. For other odd cases, Room will behave as it used to, picking the first result column that matches with the data object column.
Bug: 201306012
Bug: 212279118
Test: AmbiguousColumnResolverTest
Relnote: Room will now attempt to resolve ambiguous columns in a multimap query. This allows for JOINs with tables containing same-name tables to be correctly mapped to a result data object.
Change-Id: I4b444b042245a334cc3f362f3239721ce0b6bd1e
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/EntityRowAdapter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
A room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/AmbiguousColumnResolverTest.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
M room/room-common/api/current.txt
M room/room-compiler/src/main/kotlin/androidx/room/vo/Warning.kt
M room/room-runtime/api/restricted_current.txt
A room/room-common/src/main/java/androidx/room/AmbiguousColumnResolver.kt
M room/room-common/api/public_plus_experimental_current.txt
M room/room-common/build.gradle
M room/room-compiler/src/main/kotlin/androidx/room/processor/ProcessorErrors.kt
M room/room-common/src/main/java/androidx/room/RoomWarnings.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/MultimapQueryResultAdapter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/GuavaImmutableMultimapQueryResultAdapter.kt
M room/room-runtime/src/main/java/androidx/room/util/CursorUtil.kt
M room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
A room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/AmbiguousColumnIndexAdapter.kt
M room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/ImmutableMapQueryResultAdapter.kt
A room/room-common/src/test/java/androidx/room/AmbiguousColumnResolverTest.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/MapQueryResultAdapter.kt
M room/room-common/api/restricted_current.txt
https://android-review.googlesource.com/2064298
Branch: androidx-main
commit 894b0ff2c1b095a46803975f400a561eb974ea28
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Fri Oct 29 10:56:31 2021
Duplicate column resolution heuristic algorithm
AmbiguousColumnResolver contains an algorithm to map query result columns to data objects (POJOs) columns. We call data object columns 'mapping' and in a multimap query where there might be multiple data objects we refer to the list of all their columns 'mappings'. The algorithm uses a grouping / neighboring strategy to assign the duplicate columns to their right data objects matching their name along with taking into account the the nearby columns since in a star-projected query all columns coming from a table will appear in the result before the next table. Room will generate code that uses the algorithm at runtime if the query has a star-projection, if not then Room will use the algorithm during compile-time since the columns result order is known and fixed.
The algorithm does not solve all cases, specifically those where one of the data objects has a single column which is the duplicate column. For those situation Room will warn the user so that they alias the duplicate column. For other odd cases, Room will behave as it used to, picking the first result column that matches with the data object column.
Bug: 201306012
Bug: 212279118
Test: AmbiguousColumnResolverTest
Relnote: Room will now attempt to resolve ambiguous columns in a multimap query. This allows for JOINs with tables containing same-name tables to be correctly mapped to a result data object.
Change-Id: I4b444b042245a334cc3f362f3239721ce0b6bd1e
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/EntityRowAdapter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
A room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/AmbiguousColumnResolverTest.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
M room/room-common/api/current.txt
M room/room-compiler/src/main/kotlin/androidx/room/vo/Warning.kt
M room/room-runtime/api/restricted_current.txt
A room/room-common/src/main/java/androidx/room/AmbiguousColumnResolver.kt
M room/room-common/api/public_plus_experimental_current.txt
M room/room-common/build.gradle
M room/room-compiler/src/main/kotlin/androidx/room/processor/ProcessorErrors.kt
M room/room-common/src/main/java/androidx/room/RoomWarnings.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/MultimapQueryResultAdapter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/GuavaImmutableMultimapQueryResultAdapter.kt
M room/room-runtime/src/main/java/androidx/room/util/CursorUtil.kt
M room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
A room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/AmbiguousColumnIndexAdapter.kt
M room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/ImmutableMapQueryResultAdapter.kt
A room/room-common/src/test/java/androidx/room/AmbiguousColumnResolverTest.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/MapQueryResultAdapter.kt
M room/room-common/api/restricted_current.txt
Description
Version used: 2.2.0-alpha01
Devices/Android versions reproduced on: Pixel 3 XL / Android P
I've tried to use the new awesome Target Entity feature that introduced at 2.2.0-alpha01.
But, I encountered the Room compiler error.
It seems to happen if try inserting immutable data class using @Insert(entity = ImmutableDataClass::class)
The error message says "Cannot find setter for field.". But, the generated Dao_Impl code does not use the setter methods.
Is this a Room compiler bug?
The workaround is replacing val to var.
Here is sample codes:
```
@Database(entities = [Project::class], version = 1)
abstract class TargetEntityDatabase : RoomDatabase() {
abstract fun projectDao(): ProjectDao
}
@Entity
data class Project(
@PrimaryKey
val id: Long,
val title: String,
@ColumnInfo(defaultValue = "''")
val longDescription: String
)
data class ProjectMiniApiEntity(
val id: Long,
val title: String
)
@Dao
interface ProjectDao {
@Insert(entity = Project::class)
fun insertNewProject(projectMini: ProjectMiniApiEntity)
}
```
Gradle logs:
```
> Task :app:kaptDebugKotlin FAILED
e: ProjectMiniApiEntity.java:20: error: Cannot find setter for field.
private final long id = 0L;
^
e: ProjectMiniApiEntity.java:22: error: Cannot find setter for field.
private final java.lang.String title = null;
^
```