Realm-java: Composite @PrimaryKey from two fields

Created on 15 Aug 2018  路  8Comments  路  Source: realm/realm-java

Here my java pojo in my Android project:

public class Product extends RealmObject {
    @PrimaryKey
    private int id;
    private String name;
    private String description;
    private int order_id;
}

But the id of product is not unique. In table I can have many products with same id. The unique are combination of id and order_id. In table I can have only ONE product with same id AND order_id.

But when I try to add @PrimaryKey to order_id

public class Product extends RealmObject {
    @PrimaryKey
    private int id;
    private String name;
    private String description;
   @PrimaryKey
    private int order_id;
}

I get error on Android Studio:

e: error: A class cannot have more than one @PrimaryKey. Both "id" and "order_id" are annotated as @PrimaryKey.

So what I can do?

P.S. I update products by the next method:

  public static void updateProducts(final List<Product> incomingProductsList) {
        Realm realm = Realm.getDefaultInstance();
        try {
            realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    RealmList<Product> productsRealmList = new RealmList<>();
                    productsRealmList.addAll(incomingProductsList);
                   realm.copyToRealmOrUpdate(productsRealmList);
                }
            });
        } finally {
            realm.close();
        }
    }

O-Community T-Help

All 8 comments

Then the primary key field should be a String field that combines the two fields.

id_orderId

Has another solution? It is difficult to change type of ID. In whole project I use ID exactly with integer type.

Shame that you are using int instead of long (although I think in Realm they are mapped to the same type), you could probably do some bit-shifting magic to merge two IDs together but keep it as a single long.

I change to long

public class Product extends RealmObject {
    @PrimaryKey
    private long id;
    ...
}

Here result POJO:

public class Product extends RealmObject {
    @PrimaryKey
    private String uniqueId;
    private long id;
    private String name;
    private String description;  
    private long order_id;

    public void createUniqueKey() {
        if (order_id > 0L) {
            this.uniqueId = this.id + "_" + this.order_id;
        } else {
            this.uniqueId = this.id + "";
        }
    }

And use:

public class ProductAdapterJsonDeserializer implements JsonDeserializer<Product> {

    @Override
    public Product deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        Product product = GsonUtil.gson.fromJson(json, Product.class);
        product.createUniqueKey();
        return product;
    }
}

And now it's work fine. Is it good solution?

I think it's good solution 馃憤

@Zhuinden Realm internally handles all int as long.

Was this page helpful?
0 / 5 - 0 ratings