When using the android data-persistent library Android Room ,how can I directly insert the Comment Object into the database including all the field value, and how can I query all the value out as a Comment Object?
As I know, I can not use the Comment Object as a Entity in Room directory, because of the field replyComment is also a Comment Object. And I can not query out a Comment Object even I define a POJO using the #Relations annotation either because of the one-to-one relations and one-to-many relations all included in the Comment Object.
Is there any other way except changing the Comment Model definition, such as using foreign key, making a effect on insert action and query action?
public class Comment {
public String content;
public String id;
public Comment replyComment;
public User user;
public List<ImageMedia> images;
}
public class User{
public String id;
public String name;
}
public class ImageMedia{
public String key;
public String url;
}
Is there any other way except changing the Comment Model definition
No. You would need to create a set of entities that model the database structure, where children have foreign key columns pointing back to their parents:
CommentEntity has a foreign key back to CommentEntity for the reply
CommentEntity has a foreign key back to UserEntity
ImageMediaEntity has a foreign key back to CommentEntity
Related
I have following object:
public class Cart {
public String id;
public List<Map<Product, Double>> productsInCart;
}
In this key itself is a complex object, how to do it in firestore?
Also above object can be redesigned as following
public class Cart {
public String id;
public Map<Product, Double> productsInCart;
}
Firestore does not have any sense of "complex" keys or properties. Fields and nested object property names must be strings. If you need to store something more complex, you will need to somehow reduce it down to a unique string. One option is to use a hash of the data in the object, but you're better off redesigning your object to simply use strings as keys.
I'm writing Android app with Room Database. My database contains GroupVc entity with such code:
#Entity
public class GroupVc {
#ColumnInfo(name = "language")
private String language;
#NonNull
#PrimaryKey
#ColumnInfo(name = "name_group")
private String nameGroup;
public GroupVc(String language, String nameGroup) {
this.language = language;
this.nameGroup = nameGroup;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
#NonNull
public String getNameGroup() {
return nameGroup;
}
#NonNull
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
As you can see my entity class contains two columns where nameGroup is my PrimaryKey. In my application I want to let the user to see the full list of groups and change the name of Group DialogFragments by entering new Group's names. To implement such function I've created the next DAO #Query method:
#Dao
public interface GroupVcDao {
#Query("UPDATE groupvc SET name_group= :newName WHERE name_group= :currentName")
void updateNameOfGroup(String currentName, String newName);
}
In this QUERY I want to change name of GroupVc by getting the existing name of GroupVc from RecyclerView (currentName param) and applying new one from DialogFragment (newName param).
My problem is that this QUERY doesn't bring any effect and doesn't update the name. Although I don't get any errors or exceptions. So I need to know: does such QUERY correct? Is it possible to write Update queries where primary key is changeable value and condition at the same time?
Here is the link to my complete project on GitHub
https://github.com/LAHomieJob/VocaNote
I can't be sure, but my guess would be that your query is working, but since you're changing the primary key your database is left with an instance of the old object as well as the new one. Try checking to see if you have an object with both the old name_group and the new name_group. Also if you're looking to allow your users to change the group name, it may make sense to move your primary key to a UUID or some other key that doesn't change.
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've been trying to add Realm in my Android app. Their docs are pretty well explained & easy to follow. But it fails to explain this one particular area. I'm unable to figure out the practical use for the #Ignore annotation. I know that fields under this annotation are not persisted.
Can someone please share a few use cases. Also I wanted to know the scope of such fields. I mean, if I set an #Ignore field to some value, would that value be available to the other classes in my app for that particular launch session. If yes, then how do we access it? If no (which I guess is the case), then why do we need such a field anyway?
I've searched here and on web but couldn't find the relevant information. If out of my ignorance, I've missed upon some resource, please guide me to it.
Thanks.
Accordingly to the official documentation (see https://realm.io/docs/java/latest/) #Ignore is useful in two cases:
When you use GSON integration and your JSON contains more data than you want to store, but you still would like to parse it, and use right after.
You can't create custom getters and setter in classes extending RealmObject, since they are going to be overridden. But in case you want to have some custom logic anyway, ignored fields can be used as a hack to do that, because Realm doesn't override their getter & setters. Example:
package io.realm.entities;
import io.realm.RealmObject;
import io.realm.annotations.Ignore;
public class StringOnly extends RealmObject {
private String name;
#Ignore
private String kingName;
// custom setter
public void setKingName(String kingName) { setName("King " + kingName); }
// custom getter
public String getKingName() { return getName(); }
// setter and getter for 'name'
}
Ignored fields are accessible only from the object they were set in (same as with regular objects in Java).
UPDATE: As the #The-null-Pointer- pointed out in the comments the second point is out of date. Realm now allows having custom getters and setters in Realm models.
Here's a couple of real-world use cases:
1 - Get user's fullname:
public class User extends RealmObject {
private String first;
private String last;
#Ignore
private String fullName;
public String getFullName() {
return getFirst() + " " + getLast();
}
Get JSON representation of object:
public class User extends RealmObject {
private String first;
private String last;
#Ignore
private JSONObject Json;
public JSONObject getJson() {
try {
JSONObject dict = new JSONObject();
dict.put("first", getFirst());
dict.put("last", getLast());
return dict;
} catch (JSONException e) {
// log the exception
}
return null;
}
I've found it useful to define field names for when I am querying. For example
User.java
public class User extends RealmObject {
#Index
public String name;
#Ignore
public static final String NAME = "name";
}
And then later on I can do something like:
realm.where(User.class).equalTo(User.NAME, "John").findFirst();
This way if the schema changes from say name to id I don't have to hunt down every occurrence of "name".
Please see the the official documentation about #Ignore annotation:
The annotation #Ignore implies that a field should not be persisted to disk. Ignored fields are useful if your input contains more fields than your model, and you don’t wish to have many special cases for handling these unused data fields.
How can I make an integer or long field to be auto-incremented using annotation.
As we can read in a documentation:
One important thing to note is that ActiveAndroid creates an id field
for your tables. This field is an auto-incrementing primary key.
Maybe accessing auto-generated primary key will be enough for you?
Moreover, if you would like to create custom primary key in you model, you can check solution mentioned in GitHub issue connected with ActiveAndroid, which looks like this:
#Table(name = "Items", id = "clientId")
public class Item extends Model {
#Column(name = "id")
private long id;
}
Then, id field is custom primary key, which will be auto-incremented.
In case of ActiveAndroid ORM you do not need to write id column in model, It will automatic generate auto incremented value and you can simply use it.
I am giving a sample model below-
#Table(name="Items")
public class Item extends Model{
#Column(name="name")
public String name;
}
Instead of
#Table(name="Items")
public class Item extends Model{
#Column(name="Id")
public long id;
#Column(name="name")
public String name;
}
If item is an object of Item then you can simply get id by using
item.getId();
So, the correct model is first one. For reference you can click here.