我在DAO中得到了以下代码:
@Query("select Conversation.*, User.* from Conversation join User on Conversation.createdBy = User.userUuid where conversationUuid = :conversationUuid")
fun selectAllForOverview(conversationUuid: UUID): LiveData<List<ConversationSelectAllForOverview>>
这是ConversationSelectAllForOverview
data class ConversationSelectAllForOverview(
@Embedded(prefix = "arg0")
val arg0: DbConversation,
@Embedded(prefix = "arg1")
val arg1: DbUser
)
我读到我需要用prefix
注解我的字段,以消除字段名称相同时的错误。我得到了这个错误,我不知道如何删除它。我100%确定所有列都可用。由于DbConversation
和DbUser
是从数据库中生成的,如何解决这个问题?DbConversation
和DbUser
共享一些列,请参见此处的DbConversation
定义:https://gist.github.com/Jasperav/381243e7b3cf387bfc0e9f1343f9faeb。DbUser
看起来是一样的。
error: The columns returned by the query does not have the fields
[conversationUuid,createdBy,tsCreated,distanceMapped,showOnMap,showOnOverview,allowMessagesByInRangeRegularUsers,allowMessagesByOutOfRangeRegularUsers,stillReadableForOutOfRangeRegularUsers,freedomInReplies,title,subject,likes,latitude,longitude,hasPassword,isSubscribed,showOnMapScreen,isLiked,bypassChecks,isHidden,nsfw,currentDirectEvents,totalDirectEventsAfterLastJoin,subscriptions,userUuid,username,karma,tsCreated,allowsPrivateChats,allowsNsfw,thisUserBlockedCurrentUser,incomingFriendshipRequest,outstandingFriendshipRequest,friends,bio,appRoleMapped]
in entity.ConversationSelectAllForOverview even though they are
annotated as non-null or primitive. Columns returned by the query:
[conversationUuid,createdBy,tsCreated,distanceMapped,showOnMap,showOnOverview,allowMessagesByInRangeRegularUsers,allowMessagesByOutOfRangeRegularUsers,stillReadableForOutOfRangeRegularUsers,freedomInReplies,title,subject,likes,avatar,latitude,longitude,hasPassword,isSubscribed,showOnMapScreen,isLiked,bypassChecks,isHidden,conversationReportReasonMapped,nsfw,currentDirectEvents,totalDirectEventsAfterLastJoin,lastReadConversationEventPk,mostRecentConversationEventUuid,relevance,subscriptions,userUuid,username,karma,tsCreated,allowsPrivateChats,allowsNsfw,avatar,currentUserBlockedThisUserTsCreated,thisUserBlockedCurrentUser,searchScreenScore,recentSearchedTsCreated,userReportReasonMapped,incomingFriendshipRequest,outstandingFriendshipRequest,friends,bio,appRoleMapped]
public abstract androidx.lifecycle.LiveData<java.util.List<entity.ConversationSelectAllForOverview>>
selectAllForOverview(@org.jetbrains.annotations.NotNull()
3条答案
按热度按时间z31licg01#
您为
@Embedded
注解中的列加上前缀,同时输出列没有根据查询加上前缀。例如,ConversationSelectAllForOverview类希望在查询的输出/结果中找到名为arg0conversationUuid的列,但查询只有列conversationUuid。
不使用
select Conversation.*, User.* ....
,而需要使用AS
为输出 * 对话Uuid * 列提供 * arg0对话Uuid * 的别名**等。例如,对于两个表中的每一列,您必须使用其前缀来别名实际列。
例如,使用(仅部分调整):-
The columns returned by the query does not have the fields [showOnMap,showOnOverview ....
另一种可能适用于Room 2.5.0(未测试)的解决方案是使用
@Relation
注解代替子对象(ren)的@Embedded
注解。例如,除了以下内容之外,不进行任何其他更改:-然后使用:-
然后,它成功编译(再次不运行,见下文)。即,重复列没有问题(再次见下文)。
您还可以使用(注意函数名不同,以允许编译两者):-
@Relationship
参数,然后通过后续查询构建DbUser对象(因此使用@Transaction)。注意空间用于获取找到的最后一个值,对于类似命名的输出列,并将最后一个值应用于所有如此命名的字段。据报道,这已在2.5.0中得到修复。但尚未确认是否如此。因此,您可能会得到意想不到的结果,因此,如果您采用这种方法,则应确认值与预期值一致(即检查名称相似的列/字段的值)。
以下是一个基于问题DbConversation类代码的工作演示。但是,为了简化问题,我们编写了其他代码,另外还注解掉了许多字段。LiveData已注解掉,
.allowMainThreadQueries
已简化演示。Demo使用了两个修复程序,对于
@Relation
,使用了原始查询和建议的更合理的查询。已使用调试断点来演示3个返回集。
:-
活动代码:-
当从全新安装运行时,则调试窗口(扩展了t1??和t2??):-
可以看出,所有3个查询都产生相同的结果。因此,最简单的解决方案是
@Relation
而不是@Embedded
,并使用更简洁的查询来提取相关的DbConversation。owfi6suc2#
查看类DbConversation和DbUser,确保这些类是
@Embeddable
。如果不是,在类上添加注解。另一个解决方案是再次查看错误。它说查询返回了一堆DTO(ConversationSelectAllForOverview)不包含的列;DTO的字段是对象而不是列字段。您可以创建一个接口来接收db返回的所有列:vql8enpb3#
错误消息告诉您ConversationSelectAllForOverview类中的字段与SQL查询返回的列不匹配。具体来说,它列出了查询返回的列和类中的字段,并显示存在一些不匹配。
DbConversation和DbUser之间似乎有一些重复的列名,而您正在使用**@Embedded注解将它们都包含在ConversationSelectAllForOverview**类中。但是,您需要为每个@Embedded注解使用不同的前缀以消除字段的歧义。
例如,您可以对DbConversation字段使用前缀=“conversation_",对DbUser字段使用前缀=“user_":
然后,在SQL查询中,可以使用以下前缀引用列:
请注意,您不需要在列名本身中包含前缀,因为Room会根据**@Embedded**注解自动应用这些前缀。