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 {
// ...}
Related
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'm using the new firebase sdk for android and use the real database feature. When i use the getValue(simple.class) everything is fine. But when i want to parse a class which is a subclass, all the attribute of the mother class are null, and i have this type of error:
No setter/field for name found on class uk.edume.edumeapp.TestChild
public class TestChild extends TestMother {
private String childAttribute;
public String getChildAttribute() {
return childAttribute;
}
}
public class TestMother {
protected String motherAttribute;
protected String getMotherAttribute() {
return motherAttribute;
}
}
this function
snapshot.getValue(TestChild.class);
motherAttribute attribute is null, and I get
No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild
the Json that i parse is:
{
"childAttribute" : "attribute in child class",
"motherAttribute" : "attribute in mother class"
}
Firebaser here
This is a known bug in some versions of the Firebase Database SDK for Android: our serializer/deserializer only considers properties/fields on the declared class.
Serialization of inherited properties from the base class, is missing in the in releases 9.0 to 9.6 (iirc) of the Firebase Database SDK for Android. It was added back in versions since then.
Workaround
In the meantime you can use Jackson (which the Firebase 2.x SDKs used under the hood) to make the inheritance model work.
Update: here's a snippet of how you can read from JSON into your TestChild:
public class TestParent {
protected String parentAttribute;
public String getParentAttribute() {
return parentAttribute;
}
}
public class TestChild extends TestParent {
private String childAttribute;
public String getChildAttribute() {
return childAttribute;
}
}
You'll note that I made getParentAttribute() public, because only public fields/getters are considered. With that change, this JSON:
{
"childAttribute" : "child",
"parentAttribute" : "parent"
}
Becomes readable with:
ObjectMapper mapper = new ObjectMapper();
GenericTypeIndicator<Map<String,Object>> indicator = new GenericTypeIndicator<Map<String, Object>>() {};
TestChild value = mapper.convertValue(dataSnapshot.getValue(indicator), TestChild.class);
The GenericTypeIndicator is a bit weird, but luckily it's a magic incantation that can be copy/pasted.
This was apparently finally fixed in release 9.6.
Fixed an issue where passing a derived class to DatabaseReference#setValue() did not correctly save the properties from the superclass.
for:
No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild
put setter for TestChild class:
public class TestMother {
private String motherAttribute;
public String getMotherAttribute() {
return motherAttribute;
}
//set
public void setMotherAttribute(String motherAttribute) {
this.motherAttribute= motherAttribute;
}
}
Check this https://firebase.google.com/support/guides/firebase-android
it says
"If there is an extra property in your JSON that is not in your Java class, you will see this warning in the log files: W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage
"
Blockquote
You can get rid of this warning by putting an #IgnoreExtraProperties annotation on your class. If you want Firebase Database to behave as it did in the 2.x SDK and throw an exception if there are unknown properties, you can put a #ThrowOnExtraProperties annotation on your class.
Blockquote
I have the following code:
public class TestClass {
public ArrayList<ObjectTypes> list = new ArrayList<>();
public TestClass(){
list.add(ObjectTypes.type1);
}
}
public enum ObjectTypes {
type1,
type2,
type3,
type4,
}
fb.child("Test").setValue(new TestClass());
where fb is a DatabaseReference.
When running the code the application crashes and the following error appears:
com.google.firebase.database.DatabaseException: No properties to
serialize found on class
ObjectTypes
This problem did not appear in the old Firebase.
The problem is currently solved by enumerating the enum elements (enumerating an enum...)
In the above example:
public enum ObjectTypes {
type1(0),
type2(1),
type3(2),
type4(3),
}
Hopefully an easier less boiler plated way will be added in the future?
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 want to annotate a list of classes with a custom annotation, which I need at runtime.
My annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface CustomAnnotation {
String value() default "defaultValue";
}
My custom class is:
#CustomAnnotation
public class MyClass {
}
Now, I want to read the annotation from a class name, which I has as string. Code is without error handling (for easy handling):
String className = "com.example.MyClass";
Class clazz = Class.forName(className);
Annotation[] annotation = clazz.getAnnotation(); // is empty
Why is clazz.getAnnotation() empty? Has someone an idea?
Just tested your code - it works for me.
Only need to call getAnnotations()
The issue is definitely out of code you posted.