2017-10-21 135 views
0

我嘗試重構一些代碼並移動多個體繫結構以使用體系結構組件中的房間數據庫。房間如何使用嵌套集合模型實體

我有這樣的對象,我經常使用它,從緩存中獲取它。 這裏是什麼樣子:

public class LocationEvents { 

private Map<NexoIdentifier, Date> mDeviceFirstSeenDates; 

private ArrayDeque<LocationGeoEvent> mGeoEvents; 
private ArrayDeque<LocationRSSIEvent> mRSSIEvents; 
private Map<NexoIdentifier, ScoredLocationEvent> mHighestScores; 

///Some methods 

}

我想數據庫與此結構的模型。 所以會有像LocationGeoEvent,LocationRSSIEvent,ScoredLocationEvent這樣的實體。

他們看起來像這樣:

public class LocationGeoEvent { 

private double mLongitude; 
private double mLatitude; 
private double mAccuracy; 
private Date mTimestamp; 
} 

public class LocationRSSIEvent { 

private int mRSSI; 
private NexoIdentifier mNexoIdentifier; 
private Date mTimestamp; 
} 

public class ScoredLocationEvent { 

private float mScore; 
private NexoIdentifier mNexoIdentifier; 
private LocationRSSIEvent mLocationRSSIEvent; 
private LocationGeoEvent mLocationGeoEvent; 
private Date mScoreCalculatedTime; 
private boolean mSent; 
private boolean mPreviousSent; 
} 

NexoIdentifier是一個簡單的POJO:

class NexoIdentifier { 
abstract val partialSerialID: String 
abstract val id: String 
abstract val countryAndManufacturer: String 
} 

那麼,怎樣才能讓我用房間的關係?是否有可能將LocationEvent實體作爲一次?所以例如我想能夠獲取所有嵌套在裏面的所有列表的LocationEvent。或者也許有另一種方式來做到這一點? 也不知道如何在LocationEvents - DeviceFirstSeenDates和HighestScores中將這兩個地圖建模爲兩個獨立的實體並與其他人建立關係?但究竟如何?我可能喜歡在這個例子中的幫助,我真的堅持

UPDATE

@Entity(tableName = "location_events") 
data class LocationEvents(
    @PrimaryKey(autoGenerate = true) 
       val id: Long = 0, 
    @Embedded(prefix = "device") val mDeviceFirstSeenDates: Map<NexoIdentifier, Date> = HashMap(), 
    @Embedded(prefix = "events") val mGeoEvents: ArrayDeque<LocationGeoEvent> = ArrayDeque(), 
    val mRSSIEvents: ArrayDeque<LocationRSSIEvent> = ArrayDeque(), 
    val mHighestScores: Map<NexoIdentifier, ScoredLocationEvent> = HashMap() 
       ) { 
constructor() : this(0L, hashMapOf<NexoIdentifier, Date>(), 
     ArrayDeque(), ArrayDeque(), hashMapOf<NexoIdentifier, ScoredLocationEvent>() 
) 

}

Error:error: Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).

回答

2

您可以使用嵌入。如果你想使用前綴的變量名稱相同。

例子:

public class LocationEvents { 

@Embedded(prefix="device") private Map<NexoIdentifier, Date> mDeviceFirstSeenDates; 
@Embedded(prefix="events") private ArrayDeque<LocationGeoEvent> mGeoEvents; 
private ArrayDeque<LocationRSSIEvent> mRSSIEvents; 
private Map<NexoIdentifier, ScoredLocationEvent> mHighestScores; 
} 

或者你寫一個轉換器。 (在你的代碼更新)

public class DBConverters { 
@TypeConverter 
public static mapToString(Map<NexoIdentifier, Date value) { 
    return value == null ? null : Gson.toJson(value); 
} 

@TypeConverter 
public static Map<NexoIdentifier, Date> fromMap(String value) { 
    return value == null ? null : Gson.fromJson(value, ...); 
} 
} 

和註釋你的轉換器在你的DB類

@TypeConverters(DBConverters::class) 
abstract class YourDb : RoomDatabase() { } 

更新:

警告意味着你至少需要一個可用構造函數。爲了解決這個問題並且仍然允許「數據」類,你需要使用忽略註解,並注意你沒有任何可爲空的值。

@Ignore constructor() : this(0L, hashMapOf<NexoIdentifier, Date>(), 
     ArrayDeque(), ArrayDeque(), hashMapOf<NexoIdentifier, ScoredLocationEvent>() 

這將確保Room使用您的類的標題中使用的構造函數。

房間本身沒有「真實」relationships,但您可以創建一個「虛擬類」來保存關係。房間支持ForeignKey,它允許您在關係被更新或刪除時定義行爲。請注意,您只能使用嵌入的其他類。如果存在像你的HashMap那樣的未知類型,你將會編寫一個轉換器。

+0

謝謝,但你能看看我的更新?我忘了提及我正在使用Kotlin。我有一個沒有構造函數的錯誤,但它肯定存在 – Konrad

+0

,堅持。開始AS –