Realm Android - How can I convert RealmResults to array of objects? - android

I have an object
public class ArticleList extends RealmObject {
#PrimaryKey
private String id;
private String title;
private String subtitle;
private String image;
private String category;
}
What I want to do is to fetch result from Realm and them convert result to ArticleList[]
Fetch I do by using
RealmResults<ArticleList> results = realm.where(ArticleList.class).equalTo("category", "CategoryName").findAll();
What do I have to do next to get an array of objects ?

Simplest to convert into java ArrayList:
ArrayList<People> list = new ArrayList(mRealm.where(People.class).findAll());

List<ArticleList> unmanagedList = realm.copyFromRealm(results);
Will do it.

RealmResults has a toArray() method - also toArray(T[] contents) (note the RealmResults inheritance chain). You can use these as follows:
ArticleList[] resultArray = (ArticleList[]) results.toArray();
Or
ArticleList[] resultArray = results.toArray(new ArticleList[results.size()]);
Ideally, you'd want to use RealmResults instead. This allows you to get "free" updates to your data, as well as all the conveniences of a List.

Instead of trying to convert to an array, you should extend the abstract RealmBaseAdapter class from https://github.com/realm/realm-android-adapters to keep your results in sync.
Realm provides these classes as an example of how to create an auto-updating list with a RecyclerView or a ListView.

Related

Realm avoid updating nested object

I have an app that stores lots of data to work offline as well.
I have three classes, in a hierarchy like;
public class MainGroup
{
private UUID Oid;
private String name;
private Date CreatedOn;
}
-
public class Group
{
private UUID Oid;
private String name;
private Date CreatedOn;
private MainGruop MainGroup;
}
-
public class Product
{
private UUID Oid;
private String name;
private Date CreatedOn;
private MainGruop MainGroup;
private Group Group;
}
( Oid fields are selected as PrimaryKey with realm attribute. )
Let's say, all MainGroup objects were stored in Realm DB. Then, when i'm trying to insert Group objects, with nested MainGroup object but with only its Oid field to link its master, Realm updates the MainProduct record (with given Oid), and clear the other fields as nulls.
In same way, when i'm inserting Product objects and nested objects are includes only Oid, realm updates all fields with nulls.
So, there are more complex and deeply related objects and when i make a request to get JSON from server, i must produce a very big JSON response to keep data.
And mention to insert method; I'm creating java objects with JSON response via GSON and i'm using Realm.copyToRealmOrUpdate(obj); method to insert.
To reduce payload (JSON size, serialize and insertion process), i need to find a way to fix this issue.

Why object replace instead update in Realm?

I am working on some chat - app whith complex messages.
Messages from API stored in realm DB.
When i getting messages: call after API response, deserialization finished, messages correct:
realm.beginTransaction();
realm.copyToRealmOrUpdate(listOfBaseMessageResponses);
realm.commitTransaction();
messages in db replaced and i forced to make a List in my activity and try to handle changes by myself.
Changes tracked in activity by:
messagesChangedListener = new RealmChangeListener() {
...
}
mBaseMessageResponsesRealm = realm.allObjects(BaseMessageResponse.class);
mBaseMessageResponsesRealm.addChangeListener(messagesChangedListener);
Way to get messages:
return realm.allObjects(BaseMessageResponse.class);
BaseMessageResponse class(getters and setters exists. for better understanding not show):
#SerializedName("clr")
#Expose
#PrimaryKey
private String clr;
#SerializedName("cap")
#Expose
private String cap;
#SerializedName("eoc")
#Expose
private int eoc;
#SerializedName("list")
#Expose
private RealmList<MessageInResponse> list = new RealmList<MessageInResponse>();
...
Also MessageInResponse contain nested classes.
Why messages replaced? I try many ways to figure it out but no result.
May be some problems with PK and logic for copyToRealmOrUpdate method?

Persisting array of strings with greenDao

I'm trying to map an object to database with greenDao. But when it comes to arrays, I don't know how to do it. After receiving JSON from network and deserializing it with GSON, I have objects defined by this class:
public class Car {
Long carId;
String name;
ArrayList<String> listOfLinks;
}
In case of a a different architecture, like this:
public class Car {
Long carId;
String name;
ArrayList<Link> listOfLinks;
}
public class Link {
Long carId;
String link;
}
----
Entity cars = schema.addEntity("Car");
cars.addLongProperty("carId").primaryKey();
cars.addStringProperty("name");
Entity links = schema.addEntity("Link");
links.addStringProperty("name");
links.addIdProperty().primaryKey().notNull().autoincrement();
Property linkProperty = links.addLongProperty("carId").getProperty();
ToMany carToLinks = cars.addToMany(link, linkProperty);
It would is easy. Define some relations, define properties, add foreign key and your done. With arrays I have no clue what to do. Ideas?
That approach is not common when using relational databases.
This is commonly done using to-many relations : instead of using a list of String, you can create a Link entity and then use a list of Link.
Relation toMany is useful when you have a list of your not primitive object, that you can declare like entity that have its own id etc etc etc, and make list of entities (with toMeny). By doing that greenDao makes another table in the base for you new entity with the foreign key of the base entity that contains list. When you have list of primitive type the only way to do is to make converter that converts List into one of the primitive types that greenDao works naturally. You have to do something like this `
import org.greenrobot.greendao.converter.PropertyConverter;
import java.util.Arrays;
import java.util.List;
/**
*DOLE BREEE SQLITE BREEEEEE!!!**
*i choosed to convert List into one string
*that is going to be saved in database, and vice versa
*/
public class GreenConverter implements PropertyConverter, String> {
#Override
public List convertToEntityProperty(String databaseValue) {
if (databaseValue == null) {
return null;
}
else {
List<String> lista = Arrays.asList(databaseValue.split(","));
return lista;
}
}
#Override
public String convertToDatabaseValue(List<String> entityProperty) {
if(entityProperty==null){
return null;
}
else{
StringBuilder sb= new StringBuilder();
for(String link:entityProperty){
sb.append(link);
sb.append(",");
}
return sb.toString();
}
}
}
now above all the properties that are List you have to put
#Convert(converter=yourconverterclass.class, columnType = String.class)
#Entity
public class ShipEntry {
#Id(autoincrement = true)
private long ship_id;
private String name;
private String model;
private String manufacturer;
private String starship_class;
#Convert(converter = GreenConverter.class, columnType = String.class)
private List<String> pilots;
#Convert(converter = GreenConverter.class, columnType = String.class)
private List<String> films ;
}
you can create Converter as a inner class of entitiy, and in that case it has to be declared as staticthat is the only way i have found, but the bad side is that you can not use property that you are converting into query. There might me some typo, but i hope this helps to solve your problem
I also have the same issue, and there no answer (not in official docs, not in google). Please explain how to map List to Entity?
public class Car {
Long carId;
String name;
ArrayList<String> listOfLinks;
}
Can I do something like this?
#Entity(active = true, nameInDb = "CARS")
public class Car {
#Id
private Long id;
#NotNull
#Unique
private String remoteId;
#ToMany(joinProperties = {
#JoinProperty(name = "remoteId", referencedName = "carRemoteId")
})
private List<Links> listOfLinks;
}
#Entity(active = true, nameInDb = "LISTOFLINKS")
public class Links{
#Id
private Long id;
#NotNull
#Unique
private String remoteId;
#SerializedName("listOfLinks")
#Expose
private String listOfLinks;//is it possible?????
private String carRemoteId;
}
Since JPA 2.0, you can use an element collection to persist a Collection of value types. You just need to annotate the attribute with #ElementCollection and the persistence provider will persist the elements of the Collection in an additional database table.
#Entity
public class Author {
#ElementCollection
private List<String> phoneNumbers = new ArrayList<String>();
}
The element collection might seem easier to use than an entity with a one-to-many association. But it has one major drawback: The elements of the collection have no id and Hibernate can’t address them individually.
When you add a new Object to the List or remove an existing one, Hibernate deletes all elements and inserts a new record for each item in the List.
Let’s take a quick look at an example. The following code snippet selects an Author entity and adds a second phoneNumber to the element collection.
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Author a = em.find(Author.class, 1L);
a.getPhoneNumbers().add("42424242");
em.getTransaction().commit();
em.close();
an element collection is an easy but not the most efficient option to store a list of value types in the database. You should, therefore, only use it for very small collections so that Hibernate doesn’t perform too many SQL statements. In all other cases, a one-to-many association is the better approach.

How to convert RealmResults object to RealmList?

I have a RealmResults <Student> object. I want to convert it to RealmList <Student> object. any suggestions?
RealmList <Student> results = new RealmList<Student>();
results.addAll(realmResultList.subList(0, realmResultList.size()));
Please try and let me know if this work for you.
RealmList <Student> finalList = new RealmList<Student>();
finalList.addAll(yourRealmResults.subList(0, yourRealmResults.size()));
Since 0.87.0
Added Realm.copyFromRealm() for creating detached copies of Realm objects (#931).
Which allow just return list List<E extends RealmObject>
RealmResults implements the List interface and so does the RealmList.
RealmList <Student> results = new RealmList<Student>();
results.addAll(realmResultsList);
In new update you can use copyFromRealm method to do so :
RealmList<Student> finalList = realm.copyFromRealm(resultsAnswers);
RealmResults is returned if a query is expected to give a collection of objects (e.g. RealmQuery<E>.findAll()). Otherwise, single object queries will return a RealmObject.
Managed and Unmanaged Objects
RealmResults are managed objects, meaning they cannot be manipulated outside of Realm transactions and are confined in the thread that created them. Converting RealmResults into a RealmList will make the data unmanaged, as what #epicpandaforce pointed out, meaning the objects in the list are not connected to the database anymore and are basically normal Java objects which can be transferred in between threads and manipulated.
To convert RealmResults to a RealmList:
RealmResults<User> results = realm.where(User.class).findAll();
RealmList<Users> users = realm.copyFromRealm(results);
Changes to an unmanaged object will not in any means affect the original in the database unless a realm.copyToRealm(users), doing the opposite of copyFromRealm(), is executed after. Keep in mind that RealmLists can be managed or unmanaged, as a RealmObject from a RealmResult can have the following structure in which the RealmList in this case is a managed object:
class User {
int id;
String name;
RealmList<String> petNames;
}
Finally, copyFromRealm() returns a List so it's also possible to do
ArrayList<User> users = realm.copyFromRealm(results);
Realm has some new features check-in documentation
Realm Documentation
Realm has copyfromRealm function which we can use to convert the result to list
RealmList<Student> student=realm.copyfromRealm(Realmresult);
#JemshitIskenderov This should copy for you.
public RealmList<Student> convertResultToList(RealmResult<Student> realResultsList){
RealmList <Student> results = new RealmList<Student>();
for(Student student : realResultsList){
results.add(copy(student));
}
}
private Student copy(Student student){
Student o = new Student();
o.setCreated(student.getCreated());
o.setModified(student.getModified());
o.setDeleted(student.getDeleted());
o.setName(student.getName());
//List more properties here
return o;
}
Code:
public class RealmCollectionHelper {
public static <C extends RealmModel> RealmList<C> mapperCollectionToRealmList(Collection<C> objects){
if (objects == null){
return null;
}
RealmList<C> realmList = new RealmList<>();
realmList.addAll(objects);
return realmList;
}
}
Here my gist: https://gist.github.com/jmperezra/9b4708051eaa2686c83ebf76066071ff
Just another way of doing it:
RealmList<YourClass> dummy = new RealmList<>();
Iterator<YourClass> it = realmResultsList.listIterator();
while (it.hasNext()) {
dummy.add(it.next());
}

Storing List of objects using DataType.SERIALIZABLE in ormlite android

How to save an ArrayList using ORMlite in android my model is as follows
class Model{
#DatabaseField
public String type = "";
#DatabaseField
public String name = "";
#DatabaseField
public Date dateTime = null;
#DatabaseField
ArrayList<Item> items = null;
}
And Item class has
class Item{
#DatabaseField
String itemName;
...
}
I am getting the following exception :
java.sql.SQLException: ORMLite can't store unknown class class
java.util.ArrayList for field 'items'. Serializable fields must specify
dataType=DataType.SERIALIZABLE
But when i specify my field as
#DatabaseField(dataType = DataType.SERIALIZABLE)
ArrayList<Item> items = null;
The compiler gives a error called field cannot be resolved please help me with this.
I've just changed the error message to be:
ORMLite does not know how to store class
java.util.ArrayList for field 'items'. Use another class, custom persister, or to serialize it use dataType=DataType.SERIALIZABLE
Maybe that makes more sense? ORMLite is trying to say that it doesn't know how to store lists in a field. If you want to store collection of items then maybe you should take a look at the foreign-collection documentation.

Categories

Resources