Creating M:N relation using GreenDao

649 views
Skip to first unread message

Arnold Schmid

unread,
May 26, 2012, 3:35:53 PM5/26/12
to gree...@googlegroups.com
Good Evening,
For hours I'm trying to create an entity model to reflect my m:n relations. I have a table work, a table variety (= variety quarter) and a table work_varquarter which reflects the m:n relation. A work can done on different variety quarters, and obviously on a variety quarter can be done different works.

Code:
 Entity land = schema.addEntity("Land");
        land.addIdProperty(); //not relevant for my question
        land.addStringProperty("name").notNull();
// table variety -- OK
        Entity variety = schema.addEntity("Variety");
        variety.setTableName("Variety");
        variety.addIdProperty();
        Property varietyname = variety.addStringProperty("varietyname").notNull().getProperty();
        variety.addStringProperty("clone");
        variety.addIntProperty("plantyear");
        variety.addLongProperty("size");
        Property landId = variety.addLongProperty("landId").notNull().getProperty();
        variety.addToOne(land, landId);
   // relation to table land - OK   
        ToMany landToVariety = land.addToMany(variety, landId);
        landToVariety.setName("varieties");
        landToVariety.orderAsc(varietyname);
   //entity work    
        Entity work = schema.addEntity("work");
        work.addIdProperty();
        Property workDate = work.addDateProperty("workDate").notNull().getProperty();
        Property work_desc = work.addStringProperty("work_desc").notNull().getProperty();
   //intermediate - helper table for storing the work on the variety quarter     
      
 Entity work_varquarter = schema.addEntity("work_varquarter");
     //   work_varquarter.addIdProperty(); not needed because the primary key is constructed from workID and quarterId
        Property workId = work_varquarter.addLongProperty("workId").notNull().getProperty();
        Property quarterId = work_varquarter.addLongProperty("quarterId").notNull().getProperty();
      // work_varquarter.addToOne(work, workId); --> error here ???
      //  work_varquarter.addToOne(variety, quarterId);
       
        ToMany workToQuarter1 = work.addToMany(work_varquarter, workId); --> error here
        ToMany workToQuarter2 = variety.addToMany(work_varquarter, quarterId);

Please let me know, how I can build a m:n relation using GreeDao. Thanks
Arnold Schmid

Markus Junginger

unread,
May 28, 2012, 4:00:14 AM5/28/12
to gree...@googlegroups.com
M:N relations are currently not supported ( http://greendao-orm.com/documentation/relations/). Sorry.

For efficient M:N look ups, use a raw query (method queryRaw) using SQL.

Arnold Schmid

unread,
May 28, 2012, 12:54:31 PM5/28/12
to gree...@googlegroups.com
Thanks Markus,
but on the website is written:
While greenDAO does not support n:m relations directly as of now, you can model the join table as a separate entity. In practice, you often have “relation entities” with additional properties, so you might want to do so anyway.

I mean I have build this relation entity, namely work_varquarter. But if I define the relations between the tables, I receive an error. I have to build two addToOne connections. Please let me know how you would implement such an UseCase. Before I can start a raw query I have to create the DB structure and I like to use GreenDao.
Thanks
Arnold Schmid


Am Montag, 28. Mai 2012 10:00:14 UTC+2 schrieb Markus Junginger:
M:N relations are currently not supported ( http://greendao-orm.com/documentation/relations/). Sorry.

For efficient M:N look ups, use a raw query (method queryRaw) using SQL.

Markus Junginger

unread,
May 31, 2012, 12:43:48 PM5/31/12
to gree...@googlegroups.com
While greenDAO does not support n:m relations directly as of now, you can model the join table as a separate entity. In practice, you often have “relation entities” with additional properties, so you might want to do so anyway.
Those relation entities would need an ID (every entity needs one) and you'd add two FK properties to this entity. An efficient query can still be made only via SQL currently. If you just need a plain M:N (no additional properties justifying an entity) you could manage this SQL completely.

Markus

Swapnil Shinde

unread,
Feb 16, 2015, 7:35:08 AM2/16/15
to gree...@googlegroups.com
Hello Markus,
I have three entities Labor Union, Labor Union Local, Labor Union Class. I want to make laborUnion ToMany laborUnionLocal relationship also   laborUnionLocal ToOne laborUnion Also laborUnionLocal ToMany laborUnionClass and laborUnionClass ToOne laborUnionLocal. I have tried it, but not succeeded.  I'm too much confused with it now. Below is my code.

// Labor union Entity
        Entity laborUnion = schema.addEntity("LaborUnion");
        laborUnion.addIdProperty();
        laborUnion.addStringProperty("code");
        laborUnion.addStringProperty("desc");
        laborUnion.addBooleanProperty("isArchived");
        laborUnion.addDateProperty("lastSyncedOn");
        laborUnion.addStringProperty("name");
        laborUnion.addStringProperty("serverKey");
        laborUnion.addIntProperty("version");

        // Labor union local Entity
        Entity laborUnionLocal = schema.addEntity("LaborUnionLocal");
        laborUnionLocal.addIdProperty();
        Property laborUnionId = laborUnionLocal.addLongProperty("laborUnionId").notNull().getProperty();
        laborUnionLocal.addStringProperty("serverKey");
        laborUnionLocal.addStringProperty("code");
        laborUnionLocal.addStringProperty("desc");
        laborUnionLocal.addStringProperty("unionId");
        laborUnionLocal.addBooleanProperty("isActive");
        laborUnionLocal.addDateProperty("lastSyncedOn");
        laborUnionLocal.addStringProperty("name");
        laborUnionLocal.addIntProperty("version");

        // Labor union class entity
        Entity laborUnionClass = schema.addEntity("LaborUnionClass");
        laborUnionClass.addStringProperty("serverKey");
        laborUnionClass.addStringProperty("code");
        laborUnionClass.addStringProperty("desc");
        laborUnionClass.addBooleanProperty("isArchived");
        laborUnionClass.addDateProperty("lastSyncedOn");
        laborUnionClass.addStringProperty("unionLocalId");
        laborUnionClass.addStringProperty("name");
        laborUnionClass.addIntProperty("version");

        laborUnion.addToMany(laborUnionLocal, laborUnionId);
        laborUnionLocal.addToOne(laborUnion, laborUnionId);

        laborUnionLocal.addToMany(laborUnionClass, laborUnionId);
        laborUnionClass.addToOne(laborUnionLocal, laborUnionId);

Please let me know what is the issue in my code.

Bill

unread,
Feb 17, 2015, 5:28:54 PM2/17/15
to gree...@googlegroups.com
So, you're relationships can be expressed like this, where the arrows are specifying the to-one/to-many. Just making it a little easier to conceptualize what you're asking for. Let me know if this isn't correct. 

LaborUnion <-->>LaborUnionLocal
LaborUnionLocal <-->>LaborUnionClass



On Monday, February 16, 2015 at 7:35:08 AM UTC-5, Swapnil Shinde wrote:
Hello Markus,
I have three entities Labor Union, Labor Union Local, Labor Union Class. I want to make laborUnion ToMany laborUnionLocal relationship also   laborUnionLocal ToOne laborUnion Also laborUnionLocal ToMany laborUnionClass and laborUnionClass ToOne laborUnionLocal. I have tried it, but not succeeded.  I'm too much confused with it now. Below is my code.

// LaborUnion Entity; needs to-many to LaborUnionLocal

        Entity laborUnion = schema.addEntity("LaborUnion");
        laborUnion.addIdProperty();
        laborUnion.addStringProperty("code");
        laborUnion.addStringProperty("desc");
        laborUnion.addBooleanProperty("isArchived");
        laborUnion.addDateProperty("lastSyncedOn");
        laborUnion.addStringProperty("name");
        laborUnion.addStringProperty("serverKey");
        laborUnion.addIntProperty("version");

        // LaborUnionLocal Entity; needs to-one to LaborUnion, and to-many to LaborUnionClass

        Entity laborUnionLocal = schema.addEntity("LaborUnionLocal");
        laborUnionLocal.addIdProperty();
        Property laborUnionId = laborUnionLocal.addLongProperty("laborUnionId").notNull().getProperty(); //yes, this will be the foreign key for the first two relationships, which look good below

        laborUnionLocal.addStringProperty("serverKey");
        laborUnionLocal.addStringProperty("code");
        laborUnionLocal.addStringProperty("desc");
        laborUnionLocal.addStringProperty("unionId");
        laborUnionLocal.addBooleanProperty("isActive");
        laborUnionLocal.addDateProperty("lastSyncedOn");
        laborUnionLocal.addStringProperty("name");
        laborUnionLocal.addIntProperty("version");

        // LaborUnionClass entity; needs to-one to LaborUnionLocal

        Entity laborUnionClass = schema.addEntity("LaborUnionClass");
        laborUnionClass.addStringProperty("serverKey");
        laborUnionClass.addStringProperty("code");
        laborUnionClass.addStringProperty("desc");
        laborUnionClass.addBooleanProperty("isArchived");
        laborUnionClass.addDateProperty("lastSyncedOn");
        laborUnionClass.addStringProperty("unionLocalId");
        laborUnionClass.addStringProperty("name");
        laborUnionClass.addIntProperty("version");
           //this entity is missing a foreign key to for the required to-one relationship to LaborUnionLocal; added below
           Property laborUnionClassLaborUnionLocalID = laborUnionClass.addLongProperty("laborUnionLocalID").notNull().getProperty();
        
           //notice the updated method calls specifying the name of the relationship property you'll see in your generated class. These methods always take three arguments: the entity object you're creating the relationship to; the foreign key property involved in the association, and a string naming it whatever you want. Typically, you're going to create one foreign key property, and use it when creating two relationships: the to-many, and the to-one. Hope that makes sense. 

        laborUnion.addToMany(laborUnionLocal, laborUnionId, "laborUnionLocals"); //looks good
        laborUnionLocal.addToOne(laborUnion, laborUnionId, "laborUnion"); //good

       
           //wrong; you need to use the newly added laborUnionClassLaborUnionLocalID property here, like this (and updated with the better api)
        laborUnionLocal.addToMany(laborUnionClass, laborUnionId, "laborUnionClasses"); 
           laborUnionLocal.addToMany(laborUnionClass, laborUnionClassLaborUnionLocalID, "laborUnionClasses");
           //wrong; same reasons as previous, do this instead:
       laborUnionClass.addToOne(laborUnionLocal, laborUnionId); 
           laborUnionClass.addToOne(laborUnionLocal, laborUnionClassLaborUnionLocalID, "laborUnionLocal");

Please let me know what is the issue in my code.

Hope that helps 

Swapnil Shinde

unread,
Mar 19, 2015, 9:19:52 AM3/19/15
to gree...@googlegroups.com
I have resolved this issue.. Now i'm  stuck on How to update an particular entity. I have searched on google but not get solution. So can someone suggest me the correct solution?
Reply all
Reply to author
Forward
0 new messages