2017-10-21 17 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)内の2つのマップを他のものと関連して2つの別個のエンティティとしてモデル化する方法も正確には分かりませんか?しかし、どのように正確に?私は本当にこの例では助けに感謝します、私は本当にあなたが使用埋め込みするか

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() { } 

アップデートをあなたのコンバータに注釈を付ける(あなたのコードを更新した後):

警告は、少なくとも一つが使用可能な必要があることを意味しますコンストラクタ。それを解決し、 "データ"クラスを許可するには、アノテーションを無視し、null値を持たないように注意する必要があります。

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

これで、Roomがあなたのクラスのヘッダーで使用されているコンストラクタを使用するようになります。

ルーム自体には「実際の」relationshipsはありませんが、関係を保持する「ダミークラス」を作成できます。 RoomはForeignKeyをサポートしており、関係が更新または削除された場合の動作を定義できます。他のクラスに対してのみ組み込み関数を使用できることに注意してください。あなたのHashMapのような未知の型があるなら、コンバータを書くつもりです。

+0

ありがとうございます。私の更新版を見ることはできますか?私はKotlinを使っていると言いました。私はコンストラクタなしでエラーがありますが、現在は – Konrad

+0

です。 ASを開始 –

関連する問題