1
votes

I am using Room to store data for my entity objects. Room requires that all fields be publicly accessible(with getters/setters). I also use this object as my Model in the MVVM pattern. Since the object is used for purposes other then data storage/persistence, I would like to encapsulate the fields of my entity objects(private fields). However, I have to expose public getters/setters for my method(or declare it as public), which breaks encapsulation in my project

The only solution I found is creating a separate object specially for Room as an Entity object, then converting my model to that object during data persistence. Is there a better solution to this? Can I make the public accessors to my fields only accessible by Room and not other classes?

Answers in Java or Kotlin are ok.

If you need more information(e.g. the code for the Entity class), please feel free to leave a comment.

Thanks.

1
You were on the right way. Create a separate object when you work with DB. Better way to create apps it's to remove dependencies between the layers of app (data store - business logic - ui) - Olena Y
Yes, the solution I stated is feasible. However, with this solution, I have to convert the model into the object every time an item is added(e.g. when a user presses "Add items" button), and convert back to get the model. It is troublesome, and I need to write quite a lot of boilerplate code to manage conversions between these 2 types. For every field I add to the Model, I also have to ensure that it is reflected in the separate object, which may lead to errors. - LCZ
I would prefer if I could store the object directly in room without the need for a separate object. - LCZ

1 Answers

0
votes

Since no one posted an answer, I'm going to share what I've done.

I created a separate object specifically for Room as an Entity object, then converting my model to that object during data persistence, using a slightly modified version of the Memento Design Pattern.

In your codebase, you can add a Memento class to your original data class (lets say your data class is Data). Your memento class can be Data.Memento or DataMemento, a separate class. Your memento class should contain the same fields as the data class (you can ignore volatile variables that aren't going to be persisted, though).

And you can use similar code to convert the 2 types to-and-fro, during serialisation and deserialisation by Room.

public DataMemento toMemento() {
    return new DataMemento(/* parameters of your memento's constructor */);
}

public static Data fromMemento(DataMemento code) {
    return new Data(/* parameters of your entity's constructor */);
}