2017-10-21 3 views
0

Ich versuche, etwas Code umzuformen und verschiebe Architektur, um Room Database von Architekturkomponenten zu verwenden.Raum, wie man Entity mit verschachtelten Sammlungen modellieren kann

Ich habe ein solches Objekt, das ich oft benutze, es aus dem Cache bekommen. Hier , wie es aussieht:

public class LocationEvents { 

private Map<NexoIdentifier, Date> mDeviceFirstSeenDates; 

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

///Some methods 

}

I Datenbank mit dieser Struktur modellieren möchten. So wird es Entitäten wie LocationGeoEvent, LocationRSSEVent, ScoredLocationEvent geben.

Sie sehen wie folgt aus:

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 ist eine einfache POJO:

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

Wie kann ich die Beziehungen mit Zimmer machen? Ist es sogar möglich, das LocationEvent-Objekt einmal zu erstellen? So zum Beispiel möchte ich LocationEvent mit all dieser Liste abrufen können, die darin verschachtelt sind. Oder vielleicht gibt es einen anderen Weg, dies zu tun? Wissen auch nicht genau, wie diese 2 Karten in LocationEvents - DeviceFirstSeenDates und HighestScores - als zwei separate Entitäten im Verhältnis zu anderen modelliert werden? Aber wie genau? Ich werde wirklich in diesem Beispiel helfen schätzen, ich bin stecken wirklich

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).

Antwort

2

Sie können entweder Embedded. Wenn Sie die gleichen Namen Ihrer Variablen haben, möchten Sie Präfix verwenden.

Beispiel:

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; 
} 

Oder Sie schreiben einen Konverter für das.

Beispiel:

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, ...); 
} 
} 

Und Ihre Converter in Ihrer DB Klasse

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

Update (nach dem Code-Update) mit Anmerkungen versehen:

Die Warnung bedeutet, dass Sie benötigen mindestens eine nutzbaren Konstrukteur. Um dies zu lösen und dennoch "Daten" -Klassen zu erlauben, müssen Sie die Anmerkung ignorieren und darauf achten, dass Sie keine NULL-Werte haben.

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

Das wird sicherstellen, dass Room verwendet Ihren Konstruktor in der Kopfzeile Ihrer Klasse verwendet.

Zimmer selbst hat keine "echte" relationships, aber Sie können eine "Dummy-Klasse" erstellen, die Beziehungen hält. Room unterstützt ForeignKey, mit dem Sie ein Verhalten definieren können, wenn eine Beziehung aktualisiert oder gelöscht wird. Achten Sie darauf, dass Sie Embedded nur für andere Klassen verwenden können. Wenn es unbekannte Typen wie Ihre HashMap gibt, werden Sie einen Konverter schreiben.

+0

Danke, aber können Sie auf mein Update schauen? Ich habe vergessen zu erwähnen, dass ich Kotlin benutze. Ich habe einen Fehler ohne Konstruktor, aber es ist vorhanden – Konrad

+0

sicher, festhalten. Start AS –

Verwandte Themen