If i have for example a table Shows and i have a to-many relation to a table Actors
When inserting a Show which doesn't have id(its auto-generated), how can i insert Actors if i don't have id of the show to relate to?
Here is DaoGenerator code:
Entity show = schema.addEntity("Show");
show.setHasKeepSections(true);
show.addIdProperty();
show.addIntProperty("tvdb_id").notNull();
show.addStringProperty("title");
show.addIntProperty("year");
show.addStringProperty("url");
show.addLongProperty("first_aired");
show.addStringProperty("country");
show.addStringProperty("overview");
show.addIntProperty("runtime");
show.addStringProperty("status");
show.addStringProperty("network");
show.addStringProperty("air_day");
show.addStringProperty("air_time");
show.addStringProperty("certification");
show.addStringProperty("imdb_id");
show.addIntProperty("tvrage_id");
show.addLongProperty("last_updated");
show.addIntProperty("rating");
show.addIntProperty("votes");
show.addIntProperty("loved");
show.addIntProperty("hated");
Entity actor = schema.addEntity("Actor");
actor.addIdProperty();
actor.addStringProperty("name");
actor.addStringProperty("character");
actor.addStringProperty("image");
Property showId = actor.addLongProperty("show_id").notNull().getProperty();
ToMany showToActor= show.addToMany(actor, showId);
showToActor.setName("actors");
The ID is auto-generated when you insert the object.
So you have to insert the show before adding actors to it.
You can just call refresh() on that entity, the current copy would get updated and so its id.
Then you should take this showId and set it to each actor's show id.
show.refresh();
for (Actor actor : actors)
actor.setShowId(show.getId());
actorDao.insertAllInTx(actors);
Related
I am new to Greendao.I am writing a generator for generating entities in greendao.So,I have two entities Hospital and patient. They have a one to many relationship between them. So,a hospital can have many patients but one patient can have only one hospital. Now Property hospitalId = patient.addLongProperty("hospitalId").getProperty(); this adds a hospitalid column to patient table. and
ToMany hospitalToPatients = hospital.addToMany(patient, hospitalId);
This line creates a one to many relationship between hospital and patient.So what is the use of the lines patient.addToOne(hospital, hospitalId); and hospitalToPatients.setName("patients"); How to implement one to one,one to many,many to one and many to many relationships in greendao ?
PS: I copied this code from http://www.vertabelo.com/blog/technical-articles/a-comparison-of-android-orms
public class ProjectGenerator {
public static void main(String[] args) throws Exception {
Schema schema = new Schema(1, "com.example.project");
// hospital table
Entity hospital = schema.addEntity("Hospital");
hospital.addIdProperty();
hospital.addStringProperty("name");
// patient table
Entity patient = schema.addEntity("Patient");
patient.addIdProperty();
patient.addStringProperty("name");
Property hospitalId = patient.addLongProperty("hospitalId").getProperty();
// patient has a one assigned hospital
patient.addToOne(hospital, hospitalId);
// hospital has many patients
ToMany hospitalToPatients = hospital.addToMany(patient, hospitalId);
hospitalToPatients.setName("patients");
// trigger generation with path to the Android project
new DaoGenerator().generateAll(schema, "../project/src/main/java");
}
}
So what is the use of the lines patient.addToOne(hospital, hospitalId)
This line is creating a oneToOne relation between hospital and patient .
hospitalToPatients.setName("patients")
This is just setting the name of foreign key .
As you can see, you have already implemented implement one to one,one to many relationship in your example . patient.addToOne is an example of OneToOne relationships . hospital.addToMany is an example of OneToMany relationships . And greenDao doesn't support ManyToMany relationship directly for more details you can read this .
This is my code :
Schema schema = new Schema(1, "com.core.greendao.db");
/* Topic Model Table */
Entity topic = schema.addEntity("Topic");
topic.addLongProperty("topic_id").primaryKey();
topic.addStringProperty("group_id").notNull();
topic.addStringProperty("user_id");
topic.addStringProperty("slug");
topic.addStringProperty("message");
topic.addStringProperty("reply_count");
topic.addStringProperty("like_count");
topic.addStringProperty("anon_status");
topic.addStringProperty("link_data");
topic.addStringProperty("created_at");
topic.addStringProperty("locale");
topic.addIntProperty("status");
/* Reply Model Table */
//TODO: Topic id add for relation
Entity reply = schema.addEntity("Replies");
reply.addLongProperty("reply_id").primaryKey();
reply.addStringProperty("message");
reply.addStringProperty("reply_count");
reply.addStringProperty("like_count");
reply.addStringProperty("anon_status");
reply.addStringProperty("link_data");
reply.addStringProperty("created_at");
reply.addStringProperty("locale");
reply.addIntProperty("status");
/* User Model Table */
//TODO: Topic id to add for relation
Entity user = schema.addEntity("User");
user.addIdProperty();
user.addLongProperty("user_id");
user.addStringProperty("url");
user.addStringProperty("fullname");
user.addStringProperty("tagline");
user.addStringProperty("image");
user.addStringProperty("category_title");
/* Actions */
//TODO: Topic id and Reply id for relation
Entity actions = schema.addEntity("Actions");
actions.addIdProperty();
actions.addLongProperty("user_id");
actions.addStringProperty("url");
/*******************************************************************/
Property topicIdForTopicUser = user.addLongProperty("topic_id").notNull().getProperty();
user.addToOne(topic, topicIdForTopicUser);
Property topicIdForTopicAction = actions.addLongProperty("topic_id").notNull().getProperty();
actions.addToOne(topic, topicIdForTopicAction);
Property topicIdForReply = reply.addLongProperty("topic_id").notNull().getProperty();
reply.addToOne(topic, topicIdForReply);
/*******************************************************************/
As per the structure, topic_id is a primary key in the Topic table and is foreign key in the User, Action, and Replies tables.
I am getting proper values from the Topic table. But getting null point when I try to get values from other table on the basis of topic_id.
Any help appreciated.
You need to use .addToOne(table, property) method to specify the relationship. You also don't need to specify the id for the object, you can just use .addIdProperty() For example
Schema schema = new Schema(1, "com.core.greendao.db");
Entity user = schema.addEntity("User");
user.addIdProperty();
Entity topic = schema.addEntity("Topic");
topic.addIdProperty();
Property userId = topic.addLongProperty("user_id").notNull().getProperty()
topic.addToOne(user, userId);
See GreenDAO docs for more examples of relationships.
I am using Ormlite and I have an object that has a foreign field.
The said object also has getters and setters for it's fields.
public class Object {
#DatabaseField(foreign = true)
private Object2 foreignField;
Object() {
}
public Object2 getForeignField(){ return foreignField; }
public void setForeignField(Object2 foreignField){
this.foreignField = foreignField;
}
}
So I assumed that when I call :
Object testObject;
Object2 testObject2;
testObject.setForeignField(testObject2);
getDao.update(testObject);
It will automatically update the testObject in the database with the new foreignfield's id, but my table is not updating.
What am I doing wrong?
EDIT :
By reading the actual documentation on Ormlite, the update(Object) method will not update any foreign objects or foreign collections.
http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/dao/Dao.html#update(T)
NOTE: This will not save changes made to foreign objects or to foreign collections.
And now because of that, how do I update a foreign object on a table?
It will automatically update the testObject in the database with the new foreignfield's id, but my table is not updating.
It certainly should be.
The update(...) call doesn't compare the object with the database so a SQL UPDATE statement will be made. Have you tried turning on ORMLite logging?
If it is updating the Object with the same id from the Object2 foreignField then maybe that id is the same? When you call testObject.setForeignField(testObject2), the testObject2 should already have been created in the Object2 table. It needs to have an appropriate id field which is was gets stored in the Object table.
If you provide more details about the id field values and what the database has before and after the update, I may be able to help more.
I have three parse subclasses: Recipe, Ingredient, and RecipeIngredient. RecipeIngredient has a pointer to a Recipe, and a pointer to an Ingredient.
When I am trying to create a QueryFactory to get all the ingredients for a recipe. I am trying to do this with whereMatchesKeyInQuery, but the objectIds aren't matching. From the docs, it appears that this should be legal. What am I missing?
public MeatIngredientListAdapter(Context context, final String recipeName) {
super(context, new ParseQueryAdapter.QueryFactory<Ingredient>() {
public ParseQuery<Ingredient> create() {
ParseQuery<Ingredient> query = ParseQuery.getQuery(Ingredient.class);
query.whereEqualTo("isMeatOrFat", true);
ParseQuery<RecipeIngredient> riQuery = ParseQuery.getQuery(RecipeIngredient.class);
riQuery.whereEqualTo("recipeName", recipeName);
riQuery.include("ingredient");
riQuery.whereEqualTo("isMeatOrFat", true);
query.whereMatchesKeyInQuery("objectId", "ingredient.objectId", riQuery);
return query;
}
});
}
In your case the use of whereMatchesKeyInQuery is overkill. I might not have enough information to make this call about your app but is seems that you would be able to cut out the need for RecipeIngredient all together if you just create a Relation of the Ingredient class inside the Recipe class. This will simplify your queries and make your app more scalable and give you features (explained below). If you had a data structure like this:
Recipe Class
- Name (String)
- ingredients (Relation of the Ingredient class)
Ingredient Class
- <Columns to describe the ingredient that you already have in place>
Now you can store one recipe that "points" (using relations) to many ingredients.
So an example entry might look like this:
Recipe
Name
PB&J
ingredients
Peanut Butter //this is a relation to the Peanut Butter Ingredient object
Jelly //this is a relation to the Jelly Ingredient object
Ingredient
Name
Peanut Butter
Calories
...
Cost
...
And here in code we add the data to the classes:
ParseObject ingredient1 = new ParseObject(Ingredient.class);
ingredient1.put("Name", "Peanut Butter");
ParseObject ingredient2 = new ParseObject(Ingredient.class);
ingredient1.put("Name", "Jelly");
ParseObject recipe = new ParseObject("Recipe");
recipe.put("Name", "PB&J");
ParseRelation<ParseObject> relation = recipe.getRelation("ingredients");
relation.add(ingredient1);
relation.add(ingredient2);
recipe.saveInBackground();
The magic behind this setup is that we can now specify a recipe by name and get all ingredients like you wanted but we can also retrieve all recipes that have certain ingredient(s) in them (this is the beauty of a many-to-many relationship) and on top of that it simplifies your queries.
Now for the original query you wanted with this new setup:
ParseObject recipe = ...; // "PB&J" Recipe object.
ParseRelation relation = recipe.getRelation("ingredients");
// generate a query based on that relation
ParseQuery query = relation.getQuery();
query will hold all of the ingredients for the recipe object when the query is executed.
Now suppose you want to create a query where you get all of the recipes that contain a certain ingredient:
ParseObject ingredient = ...
ParseQuery<ParseObject> query = ParseQuery.getQuery("Recipe");
query.whereEqualTo("ingredients", ingredient); //use whereContainedIn for multiple ingredients
query will contain all Recipe objects that have the specified ingredient in their ingredients relation column when the query is executed.
I hope this helped you. Please let me know if I severely misunderstood the structure of your app - if so I will revise my answer if you give me new information but honestly I think the "middle man" RecipeIngredient is forcing you to complicate your app.
I'm using greenDao and I need to extract data from several tables similar to left-join funcionality. Here's a cite from my schema generator:
private static void genRetailers(Schema schema) {
// create retailer entity
Entity retailerEntity = schema.addEntity("Retailer");
retailerEntity.addIdProperty().notNull();
retailerEntity.addStringProperty("title");
Entity shopEntity = schema.addEntity("Shop");
shopEntity.addIdProperty().notNull();
shopEntity.addStringProperty("address");
Property retailerId = shopEntity.addLongProperty("retailerId")
.getProperty();
// (1) Retailer < - > (*) Shop
retailerEntity.addToMany(shopEntity, retailerId);
}
When I do:
return (ArrayList<Retailer>) mDaoSession.getRetailerDao()
.queryBuilder().list();
I only get contents of the Retailer table itself, however I also need Shop entity values which're null. Only after I call getShops() the entities get filled. I need to fill entities right at the first query. How is it done ?
Thanks.
Use the queryDeep method:
return mDaoSession.getRetailerDao().queryDeep(null);