I am pretty new in Room and currently doing one of my projects in which I'm supposed to insert some retrofit GSON data into it. First of all, let me show my JSON below which will give a clear structure.
{
"organization": {
"id": 0,
"title": "string",
"description": "HTML String",
"style": {
"navigationBackgroundColor": "#cd1325",
"navigationTextColor": "#ffffff",
"topBarLabel": "27July2015abcd",
"topBarBackgroundColor": "#cd1325",
"topBarTextColor": "#ffffff",
"bodyBackgroundColor": "#f5c233",
"bodyTextColor": "#646363",
"bannerBackgroundColor": "#ffffff",
"bannerTextColor": "#000000",
"buttonBackgroundColor": "#000000",
"buttonTextColor": "#ffffff",
"baseTextSize": 0,
"htmlWrapper": "string"
}
"login_options": [{
"name": "string",
"title": "EMAIL",
"description": "string",
"state": "string",
"allowed_email_domain": "string",
"restricted_email_domain": "string"
}, {
"name": "string",
"titl"e: "GOOGLE",
"description": "string",
"url": "string",
"clientId": "string",
"clientSecret": "string",
"redirectUri": "string",
"state": "string",
"nonce": "string",
"authorizationEndpointUri": "string",
"tokenEndpointUri": "string"
}
]
}
}
I am parsing this with retrofit which is working pretty well. Below are the model classes names which has created from https://www.jsonschema2pojo.org/

Ok. Now I have to insert these into the Room database through my repository for which I am facing a lot of difficulties. Can anyone help me with how to create the entities and how to insert these data models into the Room. Still not sure whether to insert the GSON models to Room or to create Entities and put the parsing data to those and then to insert. What I have tried till now.
LoginOptionsTable
@Parcelize
@Entity
public class LoginOptionsTable {
@ColumnInfo
@PrimaryKey(autoGenerate = true)
public long loginOpnId;
@ColumnInfo(name = "login_options_name")
public String name;
@ColumnInfo(name = "login_options_title")
public String title;
@ColumnInfo(name = "login_options_description")
public String description;
@ColumnInfo
public String state;
@ColumnInfo
public String allowedEmailDomain;
@ColumnInfo
public String restrictedEmailDomain;
@ColumnInfo
public String url;
@ColumnInfo
public String clientId;
@ColumnInfo
public String clientSecret;
@ColumnInfo
public String redirectUri;
@ColumnInfo
public String nonce;
@ColumnInfo
public String authorizationEndpointUri;
@ColumnInfo
public String tokenEndpointUri;
public static List<LoginOptionsTable> fromObject(List<LoginOption>
mOptions){
List<LoginOptionsTable> groups = new ArrayList<>();
for(int i=0; i<mOptions.size(); i++){
LoginOptionsTable st = new LoginOptionsTable();
st.name = mOptions.get(i).getName();
st.title = mOptions.get(i).getTitle();
st.description = mOptions.get(i).getDescription();
st.state = mOptions.get(i).getState();
st.allowedEmailDomain = mOptions.get(i).getAllowedEmailDomain();
st.restrictedEmailDomain =
mOptions.get(i).getRestrictedEmailDomain();
st.url = mOptions.get(i).getUrl();
st.clientId = mOptions.get(i).getClientId();
st.clientSecret = mOptions.get(i).getClientSecret();
st.redirectUri = mOptions.get(i).getRedirectUri();
st.nonce = mOptions.get(i).getNonce();
st.authorizationEndpointUri =
mOptions.get(i).getAuthorizationEndpointUri();
st.tokenEndpointUri = mOptions.get(i).getTokenEndpointUri();
groups.add(st);
}
return groups;
}
}
Style Entity:
@Parcelize
@Entity
public class StyleTable {
@ColumnInfo
@PrimaryKey(autoGenerate = true)
public long styleId;
@ColumnInfo
public String navigationBackgroundColor;
@ColumnInfo
public String navigationTextColor;
@ColumnInfo
public String topBarLabel;
@ColumnInfo
public String topBarBackgroundColor;
@ColumnInfo
public String topBarTextColor;
@ColumnInfo
public String bodyBackgroundColor;
@ColumnInfo
public String bodyTextColor;
@ColumnInfo
public String bannerBackgroundColor;
@ColumnInfo
public String bannerTextColor;
@ColumnInfo
public String buttonBackgroundColor;
@ColumnInfo
public String buttonTextColor;
@ColumnInfo
public Integer baseTextSize;
@ColumnInfo
public String htmlWrapper;
public static StyleTable fromObject(Style mStyle) {
StyleTable st = new StyleTable();
st.navigationBackgroundColor = mStyle.getNavigationBackgroundColor();
st.navigationTextColor = mStyle.getNavigationTextColor();
st.topBarLabel = mStyle.getTopBarLabel();
st.topBarBackgroundColor = mStyle.getTopBarBackgroundColor();
st.topBarTextColor = mStyle.getTopBarTextColor();
st.bannerBackgroundColor = mStyle.getBodyBackgroundColor();
st.bannerTextColor = mStyle.getBannerTextColor();
st.buttonBackgroundColor = mStyle.getButtonBackgroundColor();
st.buttonTextColor = mStyle.getButtonTextColor();
st.baseTextSize = mStyle.getBaseTextSize();
st.htmlWrapper = mStyle.getHtmlWrapper();
return st;
}
}
OrgEntity:
@Parcelize
@Entity(foreignKeys = {@ForeignKey(entity = StyleTable.class, parentColumns =
"styleId", childColumns = "stId"),
@ForeignKey(entity = LoginOptionsTable.class, parentColumns =
"loginOptionId", childColumns = "loginOpnId")
})
public class OrgTable {
@ColumnInfo
@PrimaryKey
public long id;
@ColumnInfo
public String title;
@ColumnInfo
public String description;
@ColumnInfo
public long stId;
//TODo make it for mutiple table
@ColumnInfo
public Long loginOptionsId;
@Ignore
public StyleTable style;
@Ignore
public List<LoginOptionsTable> loginOptions = null;
public static OrgTable fromObject(Organization organization){
OrgTable org = new OrgTable();
org.id = organization.getId();
org.title = organization.getTitle();
org.description = organization.getDescription();
StyleTable st = StyleTable.fromObject(organization.getStyle());
org.style = st;
//make the relation through Id
org.stId = st.styleId;
List<LoginOptionsTable> lo =
LoginOptionsTable.fromObject(organization.getLoginOptions());
org.loginOptions = lo;
//make the relation through Id
org.loginOptionsId = lo.get(0).loginOpnId;
return org;
}
}
DAO
@Dao
public interface OrgDAO {
@Query("SELECT * FROM OrgTable")
OrgTable getOrganization();
@Insert
void insertOrg(OrgTable org);
}
I have tried to create these, but not able to understand how to keep the relation between these and insert/get the saved data.
I have tried to create these, but not able to understand how to keep the relation between these and insert/get the saved data.
You can do this 2 ways either with:
a POJO with all three tables @Embedded (only suitable for 1 Org -> 1 Login and 1 Style)
with a POJO with the OrgTable @Embedded and with the LoginOptionsTable and StyleTable with @Relation annotations
An example of the first (all three tables @Embedded) being :-
class OrgWithLoginAndStyle {
/* Note use Query that
JOINS the Orgtable with the Login table
and JOINS the Orgtable with the Style table
*/
@Embedded
OrgTable orgTable;
@Embedded
LoginOptionsTable loginOptionsTable;
@Embedded
StyleTable styleTable;
}
An example of a Dao that utilises this is:-
@Query("SELECT * FROM OrgTable " +
"JOIN StyleTable ON StyleTable.styleId = OrgTable.stId " +
"JOIN LoginOptionsTable ON LoginOptionsTable.loginOpnId = OrgTable.loginOptionsId")
List<OrgWithLoginAndStyle> getOrganizationLoginAndStyle();
An example of the second (with @Relation annotations for the LoginOptionsTable and the StyleTable) :-
class OrganizationWithLoginOptionsAndWithStyles {
@Embedded
OrgTable orgTable;
@Relation(entity = LoginOptionsTable.class,parentColumn = "loginOptionsId",entityColumn = "loginOpnId")
List<LoginOptionsTable> loginOptionsTables;
@Relation(entity = StyleTable.class,parentColumn = "stId",entityColumn = "styleId")
List<StyleTable> styleTables;
}
An example of a Dao that utilises this is:-
@Transaction
@Query("SELECT * FROM OrgTable")
List<OrganizationWithLoginOptionsAndWithStyles> getOrganizationsLoginsAndStyles();
Note
Regarding your getOrganization query (see comment)
@Query("SELECT * FROM OrgTable")
//OrgTable getOrganization(); /* <<<<<<<<<< WRONG should be a List */
List<OrgTable> getOrganizations();
And your insertOrg
@Insert
//void insertOrg(OrgTable org)
long insertOrg(OrgTable org); /* <<<<<<<<<< might as well allow the id of the inserted row to be obtained */
Ok. Now I have to insert these into the Room database through my repository for which I am facing a lot of difficulties.
And I believe that your OrgTable FK definitions should be as per :-
@Entity(foreignKeys = {@ForeignKey(entity = StyleTable.class, parentColumns =
"styleId", childColumns = "stId"),
@ForeignKey(entity = LoginOptionsTable.class, parentColumns =
"loginOpnId", childColumns = "loginOptionsId")
})
Basic test
Using the following code as above except making the OrgDao class :-
@Dao
public interface OrgDAO {
@Query("SELECT * FROM OrgTable")
//OrgTable getOrganization(); /* <<<<<<<<<< WRONG should be a List */
List<OrgTable> getOrganizations();
@Query("SELECT * FROM OrgTable " +
"JOIN StyleTable ON StyleTable.styleId = OrgTable.stId " +
"JOIN LoginOptionsTable ON LoginOptionsTable.loginOpnId = OrgTable.loginOptionsId")
List<OrgWithLoginAndStyle> getOrganizationLoginAndStyle();
@Transaction
@Query("SELECT * FROM OrgTable")
List<OrganizationWithLoginOptionsAndWithStyles> getOrganizationsLoginsAndStyles();
@Insert
//void insertOrg(OrgTable org)
long insertOrg(OrgTable org); /* <<<<<<<<<< might as well allow the id of the inserted row to be obtained */
@Insert
long insertStyle(StyleTable styleTable);
@Insert
long insertLoginOptions(LoginOptionsTable loginOptionsTable);
}
And using :-
@Database(entities = {OrgTable.class,StyleTable.class,LoginOptionsTable.class},version = 1) abstract class OrgLoginStyleDatabase extends RoomDatabase { abstract OrgDAO getOrgDao(); }
And with an activity (note that some of your code was commented out namely the use of @Parcelize and the @Ignored Concstructors for the Entities) :-
public class MainActivity extends AppCompatActivity {
OrgLoginStyleDatabase db;
OrgDAO dao;
public static final String TAG = "OLSINFO";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = Room.databaseBuilder(this,OrgLoginStyleDatabase.class,"orgloginoptionsstyle.db")
.allowMainThreadQueries()
.build();
dao = db.getOrgDao();
StyleTable s1 = new StyleTable();
s1.bannerBackgroundColor = "X";
s1.bannerTextColor = "X";
s1.baseTextSize = 20;
s1.bodyBackgroundColor = "X";
s1.bodyTextColor = "X";
s1.buttonBackgroundColor = "X";
s1.buttonTextColor = "X";
s1.htmlWrapper = "X";
s1.navigationBackgroundColor = "X";
s1.navigationTextColor = "X";
s1.styleId = 100;
s1.topBarBackgroundColor = "X";
s1.topBarLabel = "X";
s1.topBarTextColor = "X";
long s1Id = dao.insertStyle(s1);
LoginOptionsTable l1 = new LoginOptionsTable();
l1.allowedEmailDomain = "Y";
l1.authorizationEndpointUri = "Y";
l1.clientId = "Y";
l1.clientSecret = "Y";
l1.description = "Y";
l1.loginOpnId = 1000;
l1.name = "Y";
l1.nonce = "Y";
l1.redirectUri = "Y";
l1.restrictedEmailDomain = "Y";
l1.state = "Y";
l1.title = "Y";
l1.url = "Y";
long l1Id = dao.insertLoginOptions(l1);
OrgTable o1 = new OrgTable();
o1.description = "Z";
o1.id = 10000;
o1.loginOptionsId = l1Id;
o1.stId = s1Id;
dao.insertOrg(o1);
List<OrgTable> orgTableList = dao.getOrganizations();
for(OrgTable o: orgTableList) {
logOrgTable(o,"FROM getOrganizations -> ");
}
List<OrganizationWithLoginOptionsAndWithStyles> organizationsLoginsAndStylesList = dao.getOrganizationsLoginsAndStyles();
for(OrganizationWithLoginOptionsAndWithStyles owloaws: organizationsLoginsAndStylesList) {
logOrgTable(owloaws.orgTable,"FROM (@Relations) getOrganizationsLoginsAndStyles -> ");
for(LoginOptionsTable lot: owloaws.loginOptionsTables) {
logLoginOptionsTable(lot,"\t");
}
for(StyleTable s: owloaws.styleTables) {
logStyleTable(s,"\t");
}
}
List<OrgWithLoginAndStyle> owlas = dao.getOrganizationLoginAndStyle();
for(OrgWithLoginAndStyle o: owlas) {
logOrgTable(o.orgTable,"FROM (@Embeddeds) getOrganizationLoginAndStyle -> ");
logLoginOptionsTable(o.loginOptionsTable,"\t");
logStyleTable(o.styleTable,"\t");
}
}
private void logOrgTable(OrgTable o,String preamble) {
Log.d(TAG,preamble + "OrgTable Description = " + o.description + " ID = " + o.id);
}
private void logStyleTable(StyleTable s, String preamble) {
Log.d(TAG,preamble + "StyleTable Description = " + s.topBarTextColor + " ID =" + s.styleId);
}
private void logLoginOptionsTable(LoginOptionsTable l, String preamble) {
Log.d(TAG,preamble + "LoginOptionsTable Description = " + l.description + " ID = " + l.loginOpnId);
}
}
Result
When run (will only run the once as hard coded ID's have been used) the result output to the log was :-
2021-04-12 21:51:50.981 D/OLSINFO: FROM getOrganizations -> OrgTable Description = Z ID = 10000
2021-04-12 21:51:50.987 D/OLSINFO: FROM (@Relations) getOrganizationsLoginsAndStyles -> OrgTable Description = Z ID = 10000
2021-04-12 21:51:50.987 D/OLSINFO: LoginOptionsTable Description = Y ID = 1000
2021-04-12 21:51:50.987 D/OLSINFO: StyleTable Description = X ID =100
2021-04-12 21:51:50.989 D/OLSINFO: FROM (@Embeddeds) getOrganizationLoginAndStyle -> OrgTable Description = Z ID = 10000
2021-04-12 21:51:50.989 D/OLSINFO: LoginOptionsTable Description = Y ID = 1000
2021-04-12 21:51:50.989 D/OLSINFO: StyleTable Description = X ID =100
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With