I am using greenDao in my app to persist complex object.
For example
class A{
id;
name;
List<B> list;
}
class B{
id;
name;
List<C> list;
}
class c{
id;
name;
}
I got the tables with all class fields(for all classes).
Problem:
I can see records for table A(for class A), tables B and C are empty(no records).
I am persisting object of class A like:
A toSave = //class generated by GSON
aDao = daoService.getADao();
aDao.insert(toSave);
Can you please help me to solve this issue?
Also I cannot find in the documentation if is allowed to query dao object and retrieve object of class A with all information/fields automatically?
thanks!
I have found the solution:
GreenDao is not able to persist cascade data - If you say insertOrReplace(tvShow) it will not persist list of episodes and list of moments. In order to perform that you have to persist all data separately.
For example:
TvShowDao.save(tvShows) OR TvShowDao.insertOrUpdate(tvShows);
AND
EpisodesDao.save(episodes) OR EpisodesDao.save(episodes)
AND
MomentDao.save(moments); OR MomentDao.save(moments);
Important:
Note that save...() will do
an insert for entities that have no ID and
will do an update for entities that have an ID set.
GreenDao Git Issue
In other words, you have to persist all data separately.
Related
I am searching everywhere but not found the exact way to use Inner Join on Realm DB in Android, check my code
public class UserName extends RealmObject {
private int UserID;
private String UserName;
// Getter Setters
}
public class UserDepartment extends RealmObject {
private int UserID;
private String UserDepartment;
// Getter Setters
}
In SQLite by using following query we easily get data
Select n.UserName, d.UserDepartment
FROM Name n INNER JOIN Department d
ON n.UserID=d.UserID
ORDER BY d.UserDepartment
But how to do same thing on Realm DB to get result...
Thanks in Advance!!
As you may know Realm is a non-relational database and concepts like join belongs for relational database. but if you need to have both UserName and UserDepartment in a single model class there are lots of implementations. but due to my experiences and according to realm constraints in using objects on different threads and updating objects snapshot with realm file, I suggest you to create a new entity, just like this:
class User extends RealmObject{
private int userId;
private UserName username;
private UserDepartment userDepartment;
}
whenever you insert a record into either UserName or UserDepartment you need to insert a record or update existing record in User.
I'm running into an issue with Realm, one to many relationship and updating existing entries to add more data to the relationship.
Model 1
public class Model1 extends RealmObject
{
#PrimaryKey
private String identifier;
#SerializedName("type")
private String type;
#SerializedName("additionalInfo")
private String additionalInfo;
#SerializedName("options")
private RealmList<Model2> moreModels;
}
Model 2
public class Model2 extends RealmObject
{
#SerializedName("hint")
private String hint;
#SerializedName("label")
private String label;
#SerializedName("favorite")
private boolean favorite;
#PrimaryKey
private String identifier;
}
So from an API I'm getting a list of Model1 objects, and each of those objects contains their own list of Model2 objects. Simple enough. This works well, I can add it to Realm and see the relationship.
Now my problem emerges when I make a second API call for a different user. The way I was hoping to have this work was to have the identifier property on Model2 be made up of userId + label. Therefore, each user will have their own set of Model2 objects. However, I was hoping to have only one set of Model1 objects, where its reference to Model2 objects gets updated as more are added to the Model2 table.
Instead what I got working is I keep my one set of Model1 (good), but the relationship to Model2 always gets overwritten with the latest set. So I have a table of Model2 objects that has 80 entries, but only the last 40 are connected.
So it looks like my update or insert is updating the Model1 entries in the table (GOOD) but instead of concatenating the existing relationships with the new ones, its just updating the relationships to only use the new ones. The Model2 entries are being added to their table correctly in that there are not duplicates based on the primary key. But the connection is broken.
Update Code
List<Model1> test = response.body();
try(Realm realmInstance = Realm.getDefaultInstance()) {
realmInstance.executeTransaction((realm) ->
{
realm.insertOrUpdate(test);
final RealmResults<Model> category = realm.where(Model1).findAll();
}
);
}
Yes, that is how the insertOrUpdate and copyToRealmOrUpdate methods works currently. Ideally, there would be a mode you could provide like REPLACE_LISTS or MERGE_LISTS, but right now that hasn't been implemented.
Your only choice is manually updating these relationships.
I have just started to use RealmDB and cannot figure out how to save linked object correctly, to implement a sort of foreign key
Here is my main User model.
public class UserModel extends RealmObject {
#PrimaryKey
public Long id;
public String firstName;
public String lastName;
public UserSettings userSettingsModel;
}
UserSettings Model is defined as follows.
public class UserSettingsModel extends RealmObject {
#PrimaryKey
private Long id;
public String email;
public RealmList<Car> cars;
}
And Car is a model itself.
public class Car extends RealmObject {
#PrimaryKey
private Long id;
public String model;
}
The problem is that when I am trying to save UserModel it tries to recreate all objects assigned to it. So before I saving user model I have already creates some Car objects.
I don't need to create them, but to reference like the foreign key in SQL databases. And when I am retrieving a user from the database it should automatically load all related data by primary keys.
Is it possible to achieve such behavior using Realm ?
Thanks for help. Solved this problem by using the copyToRealmOrUpdate method instead of copyToRealm.
You should create a managed object using realm.createObject(clazz, pkValue); if it doesn't exist yet, then set it as value or add it to the RealmList that you get another managed object.
You can also create managed objects from unmanaged objects with copyToRealmOrUpdate() (if the object has a primary key).
And when I am retrieving a user from the database it should automatically load all related data by primary keys.
The RealmList allows access to the related objects, and in fact, is also queryable by calling .where() on it. However, this is not based on primary keys. That feature is tracked under "computed fields".
I have the following 3 classes:
1) TvShow
#Entity
public class TvShow{
#Id
private String uuid;
private String url;
private String title;
...
#ToMany(referencedJoinProperty = "tvShowUuid")
private List<Episode> episodes;
2) Episode
#Entity
public class Episode{
#Id
private String uuid;
#ToMany(referencedJoinProperty = "episodeUuid")
private List<Moment> moments;
//FK
private String tvShowUuid;
3) Moment
#Entity
public class Moment{
#Id
private String uuid;
...
private String episodeUuid;
As you can see the relationship between them is: TvShow --> oneToMany --> Episode --> oneToMany --> Moment
Assuming I have a fully populated TvShow object (called tvShow), I am doing the following to add that object to my database:
final long rowId = daoSession.getTvShowDao().insertOrReplace(tvShow);
This correctly adds the tvShow object to the TvShow table. However, the Episode and Moment tables are NOT populated at all. The tvShow object has several Episodes and each episode has several moments. I was expecting the other 2 tables to contain that data as well, but they don't.
What am I doing wrong? Am I supposed to loop through each Episode (and in turn loop through each Moment of each episode) and insert them manually instead? =(
Maybe I will be wrong, I have had the same problem, but greenDao is not able to persist cascade data - If you say insertOrReplace(tvShow) it will not persist list of episodes and list of moments. In order to perform that you have to persist all data separately.
For example:
TvShowDao.save(tvShows) OR TvShowDao.insertOrUpdate(tvShows);
AND
EpisodesDao.save(episodes) OR EpisodesDao.save(episodes)
AND
MomentDao.save(moments); OR MomentDao.save(moments);
In other words, you have to persist all data separately.
I hope so that this helped you.
How do I create OR update a ForeignCollection in OrmLite?
If I try to simply add an object to a ForeignCollection, the add method acts as a create (insert into) method, but if the object already exists I will get an error about not having a unique primary key. I don't want duplicates to appear with autoincrementing primary keys, so this is fine to get this notice.
If I use the update method, then it will error if there is nothing to update.
It seems that the foreigncollection object doesn't have a way to tell me if an object is already existing in the database.
So is the only way to write a separate query myself, see if each object exists and drop the ones that have changed?
If you are using for example :
#DatabaseTable(tableName = "question")
public class QuestionDb implements Serializable {
#ForeignCollectionField(foreignFieldName = "question", eager = true)
private ForeignCollection<AnswerDb> answers;
}
#DatabaseTable(tableName="answers")
public class AnswerDb implements Serializable{
#DatabaseField (foreign=true,canBeNull=true,columnName=FIELD_QUESTIONID)
private QuestionDb question;
}
You will have to use the function createOrUpdate of the AnswersDB.
answerYouWantToAdd.setQuestion(yourQuestion);
answerDao.createOrUpdate(answerYouWantToAdd);