WarrenFaith
WarrenFaith

Reputation: 57672

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?

Upvotes: 1

Views: 812

Answers (1)

AlexS
AlexS

Reputation: 5345

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.

Upvotes: 4

Related Questions