I know Realm DB does not support inheritance, but does it support Recursive class elements? For example:
public class FileItem{
private String name;
ArrayList<FileItem> elements;
}
I am getting error
Type ArrayList<com.example.FileItem> elements is not supported ..
If I cannot do this I don't know how I can create levels for my file structures in a uniform way. Is there anyway around this?
Yes, Realm does support recursive data structures, but please read this section on how to create Realm model classes: https://realm.io/docs/java/latest/#models
In your case the model class should look like this:
public class FileItem extends RealmObject {
private String name;
private RealmList<FileItem> elements;
}
Related
I have an ArrayList<? extends BaseModel> that I'd like to store in Realm.
I have several classes that extend BaseModel and they're all stored in this ArrayList. Will Realm just do the right thing if I store this on disk? Each child class may have it's own additional members and methods.
I should probably just try testing this myself, but I'm away from my dev machine, so thought I'd ask anyway and answer it myself if no one gets to it first.
Thank You!
You can store list of BaseModel by call copyToRealmOrUpdate(), if BaseModel extend of RealmObject class or if implement RealmModel interface:
void storeListToRealm(List<? extends BaseModel> models) {
realm.beginTransaction();
realm.copyToRealmOrUpdate(models);
realm.commitTransaction();
}
Otherwise, you need to create "StoreModel", which you can store to realm, and mapping from BaseModel to StoreModel.
Realm generates a RealmModuleMediator class that has the following code:
public String getTableName(Class<? extends RealmModel> clazz) {
checkClass(clazz);
if (clazz.equals(com.yourpackage.somemodel)) {
return io.realm.SomeModelRealmProxy.getTableName();
} else if (clazz.equals(com.yourpackage.anothermodel)) {
return io.realm.AnotherRealmProxy.getTableName();
} else if ...
Looks to me like it makes no difference whether you pass in the subclass or the super class.
I am using Realm ORM for my app. I have 3 model classes of which two extends RealmObject while the other one does not.
public class Party extends RealmObject implements Parcelable {
#PrimaryKey
public int id;
public String name;
public String name_en;
public String name_ne;
public String address;
public String phoneNumber;
public String taxRegistrationNumber;
public String partyType;
the second class holds a field of type Party. But this does not extends RealmObject
public class CreatePurchaseOrder implements Parcelable {
public int voucherNumber;
public Date date;
public Party party;
String agent;
The third class holds a field for CreatePurchaseOrder and extends RealmObject
[public class CreatePurchaseOrderRow extends RealmObject implements Parcelable {
#PrimaryKey
public int id;
private int serialNumber;
private String specification;
private float quantity;
private float rate;
private String remarks;
private boolean fulfilled;
private CreatePurchaseOrder createPurchaseOrder;
With this approach it generates an error message
screenshot of error message
So is it necessary to extend every Model class with RealmObject?
Technically you don't have to extend RealmObject directly from your model class.
The docs say:
Realm model classes are created by extending the RealmObject base class.
Which implies that if you don't extend RealmObject, your class is not a Realm model, thus it can't be stored in a realm.
However you can also implement the RealmModel interface and annotate your model class with #RealmClass
#RealmClass
public class MyModel implements RealmModel {
}
as mentioned here:
Why do model classes need to extend RealmObject?
We need to add Realm specific functionality to your model classes. It also allows us to use generics in our APIs, making it easier to read and use. If you don’t want to extend a base class you can instead implement the RealmModel interface.
and here:
An alternative to extending the RealmObject base class is implementing the RealmModel interface and adding the #RealmClass annotation.
It is a different means to achieve the same goal. The issue you experience is the same though. You cannot store plain objects in a realm. You must hook up your model class to Realm using one of two ways mentioned above.
Do note that if you use the 2nd approach, the usage is different:
// With RealmObject
myModel.isValid();
// With RealmModel
RealmObject.isValid(myModel);
I want to use activeAndroid lib, but for now I faced with difficulties - I have BaseMessage class and plenty of sublasses, I want to pack them into one table, but it seems it's impossible.
Pseudocode:
#Table(name = "BaseMessage")
public class BaseMessage extends Model{
#Column(name = "messageContentType")
public int messageContentType;
...
public class MessagePhoto extends BaseMessage
I am using
BaseMessage.createMessage(...)
to create message of sertain type.
But when I add MessagePhoto type, it simply NOT put it into database.
Please show me the way to do it, or suggest any other ORM that can do such thing.
I have the following code which produces the error: Error:Parceler: Unable to find read/write generator for type io.realm.Realm for io.realm.RealmObject.realm
It was working all fine without extends RealmObject , however I want to use Realm to put to database easily. Is there a way to exlcude the RealmObject fields and just use the basic pojo fields for #Parcel?
#Parcel
public class Feed extends RealmObject{
int id;
public String text;
public String time_created;
String time_modified;
int comments_count;
int likes_count;
String feed_type;
int obj_id;
String image;
String user_name;
String user_earthmile_points;
boolean liked;
boolean commented;
boolean is_private;
String url;
int feed_creator_id;
}
EDIT #2: Actually, I found a way to make it work :). See the updated answer below.
EDIT #1: While the app compiles just fine, it crashes when trying to actually create a Parcel with the error: org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for io.realm.FeedRealmProxy. The Realm team has officially acknowledged that it is currently not possible to implement Parcelable on RealmObjects. It is unclear if / when this will be resolved.
With Parceler v0.2.16, you can do this:
#RealmClass // required if using JDK 1.6 (unrelated to Parceler issue)
#Parcel(value = Parcel.Serialization.BEAN, analyze = { Feed.class })
public class Feed extends RealmObject {
// ...
}
Then, use Parcels.wrap(Feed.class, feed) instead of Parcels.wrap(feed) everywhere, otherwise your app will crash with org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for io.realm.FeedRealmProxy.
All classes that extend RealmObject will have a matching RealmProxy class created by the annotation processor. Parceler must be made aware of this class. Note that the class is not available until the project has been compiled at least once.
#Parcel(implementations = { PersonRealmProxy.class },
value = Parcel.Serialization.BEAN,
analyze = { Person.class })
public class Person extends RealmObject {
// ...}
I'm wondering whether there's a way to extend the BaseDaoImpl class of ORMLite on Android. In my Android project I'm using several different Dao objects to access the different business objects. My business objects are stored in different tables and are all inherited form an BusinessObject base class which has the two members Long id; and Long objectId; where id is the real unique id of the object within the database table.
public abstract class BusinessObject{
public static final String ID_COLUMN_NAME = "_id";
public static final String OBJECT_ID_COLUMN_NAME = "object_id";
#SerializedName(value="_id")
#DatabaseField(canBeNull=false, columnName = ID_COLUMN_NAME, generatedId=true)
private int id;
#SerializedName(value="id")
#DatabaseField(canBeNull=false, columnName=OBJECT_ID_COLUMN_NAME, index=true, unique = true)
private long objectId;
}
Now I want to be able to delete business objects by id and by objectId. Deleting by id is of course already possible due to the BaseDaoImpl class. To be able to delete them also by objectId I thought about extending the BaseDaoImpl class and adding an generic method deleteByObjectId() method to it. Within the method I would delete the object using the dao's delete() method which takes a PreparedDelete statement.
public class ExtendedDaoImple<T, ID> extends BaseDaoImpl<T, ID> implements ExtendedDao<T, ID> {
protected ExtendedDaoImple(Class<T> dataClass) throws SQLException {
super(dataClass);
}
public int deleteByObjectId(long objectId) throws SQLException {
DeleteBuilder<T, ID> delBuilder = (DeleteBuilder<T, ID>) deleteBuilder();
delBuilder.where().eq(BusinessObject.OBJECT_ID_COLUMN_NAME, objectId).prepare();
return delete(delBuilder.prepare());
}
}
My problem is that I don't know how to create an instance of ExtendedDaoImpl class form the OrmLiteSqliteOpenHelper class. Normally a Dao is created by calling getDao() method of the OrmLiteSqliteOpenHelper class and passing the class of the BusinessObject the Dao should be used for. E.g.
Dao<Image, Long> imageDao = getDao(Image.class);
So is there a way to modify the OrmLiteSqliteOpenHelper class in such a way that ExtendedDaoImpl objects can be retrieved instead of a BaseDaoImpl object?
My problem is that I don't know how to create an instance of ExtendedDaoImpl class form the OrmLiteSqliteOpenHelper class...
Nicely worded question. The #DatabaseTable annotation has a field daoClass which can be used to specify the DAO class to construct.
http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/table/DatabaseTable.html#daoClass()
Here are the docs for the DaoManager.
http://ormlite.com/docs/dao-manager
Your class will need to have a constructor with ConnectionSource and Class arguments.
The solution is not well documented. Let me know if you have any ideas how I can improve the documentation.