I have a POJO parsed from an API call which looks like this
public class Article {
public Long id;
@Expose
@Serialized
According to the documentation here "There is no limit on the number of Entity or Dao classes but they must be unique within the Database." So I think you can simply declare the different classes within your database class that extends RoomDatabase
.
Have you tried simply declaring the different POJOs as different entities and including them all in the same database class?
For instance:
// Article, Topic and Media are classes annotated with @Entity.
@Database(version = 1, entities = {Article.class, Topic.class, Media.class})
abstract class MyDatabase extends RoomDatabase {
// ArticleDao is a class annotated with @Dao.
abstract public ArticleDao articleDao();
// TopicDao is a class annotated with @Dao.
abstract public TopicDao topicDao();
// MediaDao is a class annotated with @Dao.
abstract public MediaDao mediaDao();
}
This may not exactly help with the redundancy, but my initial thought would be type converters as well. I've actually successfully even implemented a parcelable
object as a column within my Room Database
using TypeConverters
and a single Dao
.
Have you tried using Gson
in your TypeConverter
class? I believe this article addresses your question more directly. It's a guide to storing objects in a room database. Again, the trick is in the type converters and declaring your object as the type token for Gson. For instance:
public class Converters {
@TypeConverter
public static List fromStringToList(String mediaListString) {
Type myType = new TypeToken>() {}.getType();
return new Gson().fromJson(mediaListString, myType);
}
@TypeConverter
public static String fromMediaListToString(List mediaItems) {
if (mediaItems== null || mediaItems.size() == 0) {
return (null);
}
Gson gson = new Gson();
Type type = new TypeToken>() {
}.getType();
String json = gson.toJson(mediaItems, type);
return json;
}
}
That addresses the things you've tried. Now on to your statement "I believe I need to transform the object to one which matches the database entity model." Actually, not necessarily. You can use the @Ignore
annotation for different creation instances or implementations of your entity, so long as there is at least one default constructor that includes the primary key
of the entry
. In your case:
@Entity(foreignKeys = {
@ForeignKey(entity = Article.class, parentColumns = "id", childColumns =
"articleId"),
@ForeignKey(entity = Topic.class, parentColumns = "id", childColumns =
"topicId"),
@ForeignKey(entity = Media.class, parentColumns = "id", childColumns =
"mediaId")
}
public class ArticlesEntry {
@PrimaryKey
public Long articleId;
@ColumnInfo(name = "topic_id")
public Long topicId;
@ColumnInfo(name = "media_id")
public Long mediaId;
private Article articleObject;
private Media mediaObject;
//default constructor
public ArticlesEntry(int id) {
this.articleId = id;
}
//You can call this anytime you add to the database with media object input
@Ignore
public ArticlesEntry(int id, Media inMedia) {
this.articleId = id;
this.mediaObject= inMedia;
}
//You can create many of these and insert as needed, the left out variables of the
//are null, note that id has to be passed b/c your primary key isn't set to
//autogenerate
@Ignore
public ArticlesEntry(int id, Article inArticle) {
this.articleId = id;
this.articleObject= articleObject;
}
//Or both objects:
@Ignore
public ArticlesEntry(int id, Media inMedia, Article inArticle) {
this.articleId = id;
this.mediaObject = inMedia;
this.articleObject= articleObject;
}
//getters and setters here...
}
If you create your ArticlesEntry
like above, you'll need to make and include the different TypeConverters
, which can all be within the same class and imported to the specific DB with @TypeConverters(MyConverters.class)
. Hope this helps!