为什么我从房间收到 class must be either @Entity or @DatabaseView 错误?

Why I get the class must be either @Entity or @DatabaseView error from room?

所以,我想实现 CrmLeadActivity 和 CrmLeadActivityRecurrence tables 之间的一对一关系。之后,我想在关系为 N-M 的另一个 table 中使用此 tablet。

如果我将 CrmLeadActivityWithRecurrence 替换为 CrmOpportunityWithEventsView 中的 CrmLeadActivity table,错误就会消失。但是我松了 CrmLeadActivityRecurrence table.

我在 CrmOpportunityRepository 中创建了一个原始查询。

具体的错误是:

CrmLeadActivityWithRecurrence.java:8: error: The class must be either @Entity or @DatabaseView.

Cannot find the child entity column `crm_opportunity_oid` in hu.crm.crmapp.ui.uimodels.CrmLeadActivityWithRecurrence

我不明白第二个错误,因为如您所见,CrmLeadActivity 包含 crm_opportunity_oid

所有实体模型都在我的 DateBaseMondule 和 Dao 类 中

所以我的模型:

CrmLeadActivity

@Entity(tableName = CrmLeadActivity.TABLE_NAME,indices = [Index(value = ["subject","start_on","crm_opportunity_oid"])])
@JsonIgnoreProperties(ignoreUnknown = true)
open class CrmLeadActivity(
    @JsonProperty("oid") @PrimaryKey @ColumnInfo(name = "oid") var oid: String = "",
    @JsonProperty("Subject") @ColumnInfo(name = "subject") var subject: String? = null,
    @JsonProperty("StartOn") @ColumnInfo(name = "start_on") var startOn: Date = Date(),
    @JsonProperty("EndOn") @ColumnInfo(name = "end_on") var endOn: Date = Date(),
    @JsonProperty("CrmOpportunityOid") @ColumnInfo(name = "crm_opportunity_oid") var crmOpportunityOid: String = "",
    @JsonProperty("Location") @ColumnInfo(name = "location") var location: String? = null,
    @JsonProperty("Description") @ColumnInfo(name = "description") var description: String? = null,
    @JsonProperty("SendNotificationToParticipant") @ColumnInfo(name = "send_notification_to_participants") var sendNotificationToParticipants: Boolean = false,
    @JsonProperty("SyncStatus") @ColumnInfo(name = "sync_status") var syncStatus: Int? = null,
    @JsonProperty("CrmLeadActivityHrPersonRows") @Ignore open var crmLeadActivityHrPersonRows : List<CrmLeadActivityHrPerson> = emptyList()
)

CrmLeadActivityRecurrence

@Entity(tableName = CrmLeadActivityRecurrence.TABLE_NAME)
@JsonIgnoreProperties(ignoreUnknown = true)
open class CrmLeadActivityRecurrence(
    @PrimaryKey @ColumnInfo(name = "oid") var oid: String = "",
    @ColumnInfo(name = "start_time") var startTime: Date? = null,
    @ColumnInfo(name = "end_time") var endTime: Date? = null,
    @ColumnInfo(name = "date_number") var dateNumber: Int? = null,
    @ColumnInfo(name = "recurrence_type") var recurrenceType: Int? = null,
    @ColumnInfo(name = "crm_lead_activity_oid") var crmLeadActivityOid: String = "",
    @ColumnInfo(name = "day_of_week") var dayOfWeek: Int? = null,
    @ColumnInfo(name = "recurrence_range") var recurrence_range: Int? = null
)

关系Table:

data class CrmLeadActivityWithRecurrence(
    @Relation(
        parentColumn = "oid",
        entityColumn = "crm_lead_activity_oid",
    )
    var crmLeadActivityRecurrence: CrmLeadActivityRecurrence? = null
): CrmLeadActivity()

另一个Table:

@Entity(tableName = CrmOpportunity.TABLE_NAME,indices = [Index(value = ["short_name","customer_oid","sale_date","close_date","guidance_date","mapping_date"])])
@JsonIgnoreProperties(ignoreUnknown = true)
open class CrmOpportunity(
    @JsonProperty("Oid") @PrimaryKey @ColumnInfo(name = "oid") var oid: String = "",
    @JsonProperty("ShortName") @ColumnInfo(name = "short_name") var shortName: String? = "",
    @JsonProperty( "CustomerOid") @ColumnInfo(name = "customer_oid") var customerOid: String = ""

//There are more propoerties, but I think it is not important
}

还有另一个关系table:

class CrmOpportunityWithEventsView(
    @Relation(
        parentColumn = "oid",
        entityColumn = "crm_opportunity_oid"
    )
    var crmLeadActivities: List<CrmLeadActivityWithRecurrence> = emptyList()
) : CrmOpportunity() {}

存储库:

fun getProjectWithEvent(
        searchText: String?,
        fromDate: Long,
        toDate: Long,
        hrPerson: String?
    ): LiveData<PagedList<CrmOpportunityWithEventsView>> {
        val sb = StringBuilder()
        val bindLists = ArrayList<Any>()

        sb.append("SELECT t1.* , count(t2.oid) FROM ${CrmOpportunity.TABLE_NAME} t1 LEFT JOIN ${CrmLeadActivity.TABLE_NAME} t2 ON t1.oid = t2.crm_opportunity_oid ")
        sb.append(" LEFT JOIN ${CrmLeadActivityHrPerson.TABLE_NAME} t3 ON t2.oid = t3.crm_lead_activity_oid ")
        sb.append(" LEFT JOIN ${CrmLeadActivityRecurrence.TABLE_NAME} t4 ON t2.oid = t4.crm_lead_activity_oid ")
        sb.append("WHERE (t1.short_name like ? ")
        bindLists.add(CommonUtils.sqlLikeQuery(searchText,true))
        sb.append(" OR t2.subject like ? ) ")
        bindLists.add(CommonUtils.sqlLikeQuery(searchText,true))

        sb.append(" AND t3.hr_person_oid LIKE ?")
        bindLists.add(CommonUtils.sqlLikeQuery(hrPerson,true))

        sb.append(" AND ((t2.start_on >= ? ")
        bindLists.add(fromDate)
        sb.append(" AND t2.start_on <= ? ) OR")
        bindLists.add(toDate)

        sb.append(" ( t4.start_time <= ? AND t4.end_time >= ? ))")
        bindLists.add(fromDate)
        bindLists.add(fromDate)

        sb.append(" GROUP BY t1.oid HAVING count(t2.oid) > 0 ORDER BY t1.oid")

        val simpleSqLiteQuery = SimpleSQLiteQuery(sb.toString(), bindLists.toTypedArray())

        val config = PagedList.Config.Builder()
            .setEnablePlaceholders(true)
            .setPageSize(50)
            .setPrefetchDistance(50)
            .setInitialLoadSizeHint(50 * 2).build()

        return LivePagedListBuilder(
            crmOpportunityDao.getProjectWithEvents(simpleSqLiteQuery),
            config
        ).build()
    }

道:

@RawQuery(observedEntities = [CrmOpportunity::class, CrmLeadActivity::class,CrmLeadActivityHrPerson::class,CrmLeadActivityRecurrence::class])
abstract fun getProjectWithEvents(simpleSQLiteQuery: SimpleSQLiteQuery): DataSource.Factory<Int, CrmOpportunityWithEventsView>

问题

I dont understand the second error, because as you can see, CrmLeadActivity contains the crm_opportunity_oid

BUT 该消息并不是说 CrmLeadActivity 应该或不包含 crm_opportunity_oid.

消息说在 CrmLeadActivityWithRecurrence.

中找不到 crm_opportunity_oid

这是因为:-

class CrmOpportunityWithEventsView(
    @Relation(
        parentColumn = "oid",
        entityColumn = "crm_opportunity_oid"
    )
    var crmLeadActivities: List<CrmLeadActivityWithRecurrence> = emptyList()
) : CrmOpportunity() {}

所以消息 CrmLeadActivityWithRecurrence.java:8: error: The class must be either @Entity or @DatabaseView.CrmLeadActivityWithRecurrence 不是 table,它不是,它是一个 POJO从相关的 tablesCrmLeadActivity.TABLE_NAMECrmLeadActivityRecurrence.TABLE_NAME).

修复

因此,您需要使用@Relation 的 entity 参数来识别 table,让 room 知道 table 期望获得crm_opportunity_oid 来自.

  • 默认情况下(省略 entity = ?::class@Relation 默认为 table 与注释所针对的 var/val 关联。因此它尝试查看与 CrmLeadActivityWithRecurrence 关联的 table 并且它不是 table (第一条消息)然后它说(第二条消息)它找不到该列crm_oppurtunity_oid 因为 CrmLeadActivityWithRecurrence 不是 table.

因此我相信你想要:-

class CrmOpportunityWithEventsView(
    @Relation(
        entity = CrmLeadActivity::class, /*<<<<<<<<<< ADDED */
        parentColumn = "oid",
        entityColumn = "crm_opportunity_oid"
    )
    var crmLeadActivities: List<CrmLeadActivityWithRecurrence> = emptyList()
) : CrmOpportunity() {}
  • 请注意修复代码尚未编译或 运行 因此可能包含 errors/typos,它仅作为 原则上的 代码.