Android,Realm:After add annotation@PrimaryKey get错误:以下更改无法在仅添加模式下进行:
领域3.5.0。 我从外部系统获取json。我需要将这个json保存到Realm 此处:Android,Realm:After add annotation@PrimaryKey get错误:以下更改无法在仅添加模式下进行:,android,realm,Android,Realm,领域3.5.0。 我从外部系统获取json。我需要将这个json保存到Realm 此处: { "id": 1, "address": "Address 1", "contactsIds": [10, 20, 30, 40], "name": "Person 1" } 在我的Android应用程序中: 因此,我为Person创建了POJO: public class Person extends RealmObject { @PrimaryKey
{
"id": 1,
"address": "Address 1",
"contactsIds": [10, 20, 30, 40],
"name": "Person 1"
}
在我的Android应用程序中:
因此,我为Person创建了POJO:
public class Person extends RealmObject {
@PrimaryKey
private int id;
@Required
private String name;
private String address;
private RealmList<RealmInt> contactsIds = new RealmList<>();
}
我的RealmInt自定义json反序列化程序(由GSON提供):
调用方法“fromJsonToRealm”的结果是:
- 在表“Person”中创建了一条记录
- 在表“RealmInt”中创建了4条记录(10、20、30、40)
private void setRealmDefaultConfiguration(SyncUser syncUser) {
SyncConfiguration config = new SyncConfiguration.Builder(syncUser, REALM_URL).build();
Realm.setDefaultConfiguration(config);
}
所以现在我想更新这个人。
我得到了新的json(对于相同的人),其中包含更新的数据:
{
"id": 1,
"address": "Address new",
"contactsIds": [10, 20],
"name": "Person new"
}
我再次启动方法“fromJsonToRealm”,结果它成功地更新了表“Person”中的一条记录,但在表“RealmInt”中添加了新的2条记录。
结果在表“RealmInt”中,我有6条记录
但我想在更新同一对象“Person”时更新(而不是插入)表“RealmInt”中的记录
因此,我将注释@PrimaryKey添加到对象“RealmInt中的字段“value”
但当我从JSONTORealm重新启动方法“”时,我得到错误:
E/REALM_JNI( 9018): jni: ThrowingException 8, The following changes cannot be made in additive-only schema mode:
E/REALM_JNI( 9018): - Primary Key for class 'RealmInt' has been added., .
E/REALM_JNI( 9018): Exception has been thrown: The following changes cannot be made in additive-only schema mode:
E/REALM_JNI( 9018): - Primary Key for class 'RealmInt' has been added.
所以问题是:当获取同一对象的更新json时,如何更新表“Person”中的exist记录?添加/删除
@PrimaryKey
被视为“破坏性”模式操作,因此在同步模式下不允许
使用当前的模式设置,在复制新用户之前,应该从域中删除现有的RealmInt
s
public void fromJsonToRealm(final String someJson) {
try(Realm realm = Realm.getDefaultInstance()) {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = JsonUtil.gson.fromJson(someJson, Person.class);
long personId = person.getId();
Person managedPerson = realm.where(Person.class).equalTo("id", personId).findFirst();
if(managedPerson != null) {
managedPerson.getContactIds().deleteAllFromRealm();
}
realm.copyToRealmOrUpdate(person);
}
});
}
另一个选择是实现一些更智能的合并逻辑
public void fromJsonToRealm(final String someJson) {
try(Realm realm = Realm.getDefaultInstance()) {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = JsonUtil.gson.fromJson(someJson, Person.class);
long personId = person.getId();
Person managedPerson = realm.where(Person.class).equalTo("id", personId).findFirst();
if(managedPerson != null) {
boolean wasFound = false;
for(RealmInt existingInt : managedPerson.getContactIds()) {
for(RealmInt newInt : person.getContactIds()) {
if(existingInt.getValue() == newInt.getValue()) {
wasFound = true;
break;
}
}
if(!wasFound) {
existingInt.deleteFromRealm();
}
}
Iterator<RealmInt> newIntIterator = person.getContactIds().iterator();
while(newIntIterator.hasNext()) {
RealmInt newInt = newIntIterator.next();
boolean wasFound = false;
for(RealmInt existingInt : managedPerson.getContactIds()) {
if(existingInt.getValue() == newInt.getValue()) {
wasFound = true;
break;
}
}
if(!wasFound) {
newIntIterator.remove();
}
}
}
realm.copyToRealmOrUpdate(person);
}
});
}
public void fromJsonToRealm(最终字符串someJson){
try(Realm-Realm=Realm.getDefaultInstance()){
realm.executeTransactionAsync(新realm.Transaction(){
@凌驾
公共void执行(领域){
Person-Person=JsonUtil.gson.fromJson(someJson,Person.class);
long personId=person.getId();
Person-managedPerson=realm.where(Person.class).equalTo(“id”,personId).findFirst();
if(managedPerson!=null){
布尔值wasFound=false;
对于(RealmInt existingInt:managedPerson.getContactIds()){
for(RealmInt newInt:person.getContactIds()){
如果(existingInt.getValue()==newInt.getValue()){
wasFound=true;
打破
}
}
如果(!wasFound){
existingInt.deleteFromRealm();
}
}
迭代器newIntIterator=person.getContactIds().Iterator();
while(newIntIterator.hasNext()){
RealmInt newInt=newIntIterator.next();
布尔值wasFound=false;
对于(RealmInt existingInt:managedPerson.getContactIds()){
如果(existingInt.getValue()==newInt.getValue()){
wasFound=true;
打破
}
}
如果(!wasFound){
newIntIterator.remove();
}
}
}
realm.copyToRealmOrUpdate(个人);
}
});
}
另外,我不使用
RealmList
S,我更喜欢将它们保存为逗号分隔的字符串。不过,Realm Core 3.0.0将使此用例更容易使用。仅添加模式模式
您正在使用SyncConfiguration,对吗?是的。这里的代码:私有void setRealmDefaultConfiguration(SyncUser SyncUser){SyncConfiguration config=new SyncConfiguration.Builder(syncUser,REALM_URL).build();REALM.setDefaultConfiguration(config);}
。表“Person”和“RealmInt”必须与许多其他android设备共享。所以您认为使用Field personsIds作为字符串是更好的方法吗?Smt如下:public class Person extends RealmObject{@PrimaryKey private int id;@必需的私有字符串名称;私有字符串地址;//逗号分隔的字符串,例如“[10,20,30]”私有字符串contactsIds;}
?是的,类似的。这取决于您以后查询它们的方式,因为如果您需要查询包含,并且您的ID可以同时包含10
和100
,那么类似,10100,
的内容更好,因为这样您可以查询,“+number+”,”
以可靠的方式。这是我经常考虑的,考虑到RealmList
还不受支持(虽然下一个主要版本将有核心支持,所以它将在几个月后出现)。
E/REALM_JNI( 9018): jni: ThrowingException 8, The following changes cannot be made in additive-only schema mode:
E/REALM_JNI( 9018): - Primary Key for class 'RealmInt' has been added., .
E/REALM_JNI( 9018): Exception has been thrown: The following changes cannot be made in additive-only schema mode:
E/REALM_JNI( 9018): - Primary Key for class 'RealmInt' has been added.
public void fromJsonToRealm(final String someJson) {
try(Realm realm = Realm.getDefaultInstance()) {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = JsonUtil.gson.fromJson(someJson, Person.class);
long personId = person.getId();
Person managedPerson = realm.where(Person.class).equalTo("id", personId).findFirst();
if(managedPerson != null) {
managedPerson.getContactIds().deleteAllFromRealm();
}
realm.copyToRealmOrUpdate(person);
}
});
}
public void fromJsonToRealm(final String someJson) {
try(Realm realm = Realm.getDefaultInstance()) {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = JsonUtil.gson.fromJson(someJson, Person.class);
long personId = person.getId();
Person managedPerson = realm.where(Person.class).equalTo("id", personId).findFirst();
if(managedPerson != null) {
boolean wasFound = false;
for(RealmInt existingInt : managedPerson.getContactIds()) {
for(RealmInt newInt : person.getContactIds()) {
if(existingInt.getValue() == newInt.getValue()) {
wasFound = true;
break;
}
}
if(!wasFound) {
existingInt.deleteFromRealm();
}
}
Iterator<RealmInt> newIntIterator = person.getContactIds().iterator();
while(newIntIterator.hasNext()) {
RealmInt newInt = newIntIterator.next();
boolean wasFound = false;
for(RealmInt existingInt : managedPerson.getContactIds()) {
if(existingInt.getValue() == newInt.getValue()) {
wasFound = true;
break;
}
}
if(!wasFound) {
newIntIterator.remove();
}
}
}
realm.copyToRealmOrUpdate(person);
}
});
}