Barock
Barock

Reputation: 439

How to get a recursive many-to-many relation with greenDao

I want to get a recursive data structure of categories.


OOM structure:

category_structure_oom

A category should manage a list or a set of (sub)categories.


ROM structure:

category_structure_rom

physical structure of ROM:

category (_id_, title)
overAndSubCategories (ocId, scId)

Both properties of overAndSubCategories are foreign keys and refer the id of category.

The title of category is unique and could be a primary key but greenDao does not support a string as primary key so far. So I add a id as documented.


GreenDao does not support many to many relations. Am I able to implement an equivalent scheme that solve this structure problem?

*both images powered by yEd

Upvotes: 1

Views: 404

Answers (1)

Barock
Barock

Reputation: 439

I am not sure that this solution is correct or the best because I do not know 100% what I do but it works.

The scheme generator:

final Entity category = schema.addEntity("Category");
category.addIdProperty();
category.addStringProperty("Name").notNull().unique().index();

final Entity overSubCategory = schema.addEntity("OverSubCategory");
// no own id! we do not want to load objects of this type
final Property fkOverCategory = overSubCategory.addLongProperty("IdO").notNull().getProperty();
final Property fkSubCategory = overSubCategory.addLongProperty("IdS").notNull().getProperty();
overSubCategory.addToOne(category, fkOverCategory, "OverCategory");
overSubCategory.addToOne(category, fkSubCategory, "SubCategory");

Usage of this scheme:

/* # write # */

final CategoryDao categoryDao = session.getCategoryDao();
final OverSubCategoryDao overSubCategory = session.getOverSubCategoryDao();

// overcategories
final Category oC1 = new Category(1l, "food and drink");
final Category oC2 = new Category(2l, "party");
// subcategories
final Category sC1 = new Category(3l, "junkfood");
final Category sC2 = new Category(4l, "restaurante");
final Category sC3 = new Category(5l, "pub");

categoryDao.insert(oC1);
categoryDao.insert(oC2);
categoryDao.insert(sC1);
categoryDao.insert(sC2);
categoryDao.insert(sC3);

overSubCategory.insert( new OverSubCategory(oC1.getId(), sC1.getId()) );
overSubCategory.insert( new OverSubCategory(oC1.getId(), sC2.getId()) );
overSubCategory.insert( new OverSubCategory(oC1.getId(), sC3.getId()) );
overSubCategory.insert( new OverSubCategory(oC2.getId(), sC3.getId()) );

/* # read # */

final QueryBuilder<Category> cqb = categoryDao.queryBuilder();
// all categories that are subcategories and ...
final Join joinOverSubCategories = cqb.join(OverSubCategory.class, OverSubCategoryDao.Properties.IdS);
// ... whose overcategories ...
final Join joinSubCategories = cqb.join(joinOverSubCategories, OverSubCategoryDao.Properties.IdO, Category.class, CategoryDao.Properties.Id);
// ... named "food and drink".
joinSubCategories.where(CategoryDao.Properties.Name.eq("food and drink"));

final List<Category> someSubcategories = cqb.list();

Two joins plus a where condition seem to be a bit to much. Better solutions are desirable.

Upvotes: 1

Related Questions