androiddatabaseandroid-sqlitegreendaogreendao-generator

Make a relationship to a column that is not the primary key


I am currently switching from ORMlite to GreenDao and I have trouble creating my database model in greendao.

My content is fetched from a server where the server identifies the entries with generated primary keys as String. My internal database has primary keys as Long (like Android requires).

When I sync, I need to create relations based on the keys (here "backendId") delivered by the server to make my sync way way easier.

In ORMlite I could say which column should be used to create the relationship on. The same I try to create for greendao but I fail.

Here is what I try: A sector can have an asset. The "assetId" should contain the value that is stored in "backendId" of Asset.

Any ideas how I can achieve that?

Entity asset = schema.addEntity("Asset");
asset.setSuperclass("Backend");
asset.addIdProperty().index();
asset.addStringProperty("backendId").index();
asset.addStringProperty("title");
asset.addStringProperty("description");
asset.addStringProperty("contentType");
asset.addStringProperty("url");

Entity sector = schema.addEntity("Sector");
sector.setSuperclass("Backend");
sector.addIdProperty().index();
sector.addStringProperty("backendId").index();
sector.addStringProperty("title");
sector.addToOne(asset, sector.addLongProperty("asset").getProperty(), "assetId");

// insert test:
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "greenmodel-db", null);
SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
DaoSession daoSession = daoMaster.newSession();
AssetDao assetDao = daoSession.getAssetDao();
SectorDao sectorDao = daoSession.getSectorDao();

Asset asset = new Asset(1l, "12345", "Title", "Description", "type", "url");
assetDao.insert(asset);

Sector sector = new Sector();
sector.setTitle("title");
sector.setBackendId("123");
sector.setAssetId(asset);
sectorDao.insert(sector);

The result of that insert is, that the "assetId" is the primary key of the asset table but I need it to be the "backendId".

Any ideas?


Solution

  • At the moment your only chance may be to use String-primary keys (if that's possible with your data).

    You can try something like this:

    Entity asset = schema.addEntity("Asset");
    asset.setSuperclass("Backend");
    asset.addStringProperty("backendId").index().primaryKey();
    asset.addStringProperty("title");
    asset.addStringProperty("description");
    asset.addStringProperty("contentType");
    asset.addStringProperty("url");
    
    Entity sector = schema.addEntity("Sector");
    sector.setSuperclass("Backend");
    sector.addIdProperty().index();
    Property fkAsset = sector.addStringProperty("backendId").index();
    sector.addStringProperty("title");
    sector.addToOne(asset, fkAsset, "Asset");
    

    And then use this to test:

    Asset asset = new Asset("12345", "Title", "Description", "type", "url");
    assetDao.insert(asset);
    
    Sector sector = new Sector();
    sector.setTitle("title");
    sector.setAsset(asset);
    sectorDao.insert(sector);
    

    Update

    I know greendao does not garantee to work correctly with using other primary keys than Long. But building relations seem to work, although I never tested it myself. See this post. I had a look at the sources and I didn't find a reason, why it should not work.

    Looking at the sources I don't think referencing something other than the primary key is possible at the moment.

    If you want to use the standard id primary key a workaround would also be to calculate the ids from the string values in the keep sections and use a "normal" greendso toOne mapping.