Closed ghost closed 7 years ago
Do the query inside the transaction.
Still same effect
It is ok that RealmList is null during transaction, realm should take care of creating RealmList right?
EDIT:
I checked in stetho and I have created relationship, id are assigned to connectedDevices but when I fetch devices RealmList is null
Hi @dzakens
You don't need to call realm.copyToRealmOrUpdate(device);
since the device
is already managed object.
And getter of RealmList
field never return null
since the generated code always returns non-null object like following.
if (connectedDevicesRealmList != null) {
return connectedDevicesRealmList;
} else {
LinkView linkView = proxyState.getRow$realm().getLinkList(columnInfo. connectedDevicesIndex);
connectedDevicesRealmList = new RealmList< DeviceEntity>(DeviceEntity.class, linkView, proxyState.getRealm$realm());
return connectedDevicesRealmList;
}
You can find DeviceEntityRealmProxy#realmGet$connectedDevices()
in build/generated
directory.
DeviceEntity device = realm.where(DeviceEntity.class).equalTo(Constants.DEVICE_PARAM_DEVICE_ID, deviceId).findFirst();
device.getConnectedDevices() always return null after such query, maybe I misunderstand something, but I assume that it should not be null
You're probably overwriting the managed object with an unmanaged object that doesn't have any elements in the list then, but that also means the error is elsewhere.
You're probably overwriting the managed object with an unmanaged object that doesn't have any elements in the list then, but that also means the error is elsewhere.
is there any way to check is object is managed or not ?
RealmObject
has isManaged()
method to check that
return Observable.create(new Observable.OnSubscribe<DeviceDomain>() {
@Override
public void call(final Subscriber<? super DeviceDomain> subscriber) {
final Realm realm = Realm.getDefaultInstance();
try {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
DeviceEntity device = realm.where(DeviceEntity.class).equalTo(Constants.DEVICE_PARAM_DEVICE_ID, deviceId).findFirst();
DeviceEntity deviceToBeAdded = realm.where(DeviceEntity.class).equalTo(Constants.DEVICE_PARAM_DEVICE_ID, deviceIdToAdd).findFirst();
if (device != null && deviceToBeAdded != null) {
device.getConnectedDevices().add(deviceToBeAdded);
realm.copyToRealmOrUpdate(device);
realm.copyToRealmOrUpdate(deviceToBeAdded);
subscriber.onCompleted();
}
}
});
} finally {
if (realm != null) {
realm.close();
}
}
}
});
repository.addDeviceToControlled(deviceId, deviceIdToAdd)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<DeviceDomain>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(DeviceDomain deviceDomain) {
}
});
Anything wrong here ? I spend next day on finding solution and it seems rx cannot cooperate with executeTransaction
I guess deviceId
and deviceIdToAdd
are not in your Realm, but you are just ignoring that with an if
. Try to log it.
deviceId nad deviceIdToAdd are available in Realm, I can see them through Stetho Realm plugin and via debugger
In that case your problem is that you send onCompleted()
while the transaction hasn't been committed yet, and the Realm on the main thread is updated with some delay and therefore you should use RealmChangeListener or results.asObservable()
return Observable.create(new Observable.OnSubscribe<DeviceDomain>() {
@Override
public void call(final Subscriber<? super DeviceDomain> subscriber) {
final Realm realm = Realm.getDefaultInstance();
final DeviceEntity device = realm.where(DeviceEntity.class).equalTo(Constants.DEVICE_PARAM_DEVICE_ID, deviceId).findFirst();
final DeviceEntity deviceToBeAdded = realm.where(DeviceEntity.class).equalTo(Constants.DEVICE_PARAM_DEVICE_ID, deviceIdToAdd).findFirst();
if (device != null && deviceToBeAdded != null) {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(final Realm realm) {
device.getConnectedDevices().add(deviceToBeAdded);
realm.copyToRealmOrUpdate(device);
device.addChangeListener(new RealmChangeListener<DeviceEntity>() {
@Override
public void onChange(DeviceEntity element) {
device.getConnectedDevices().size();
subscriber.onCompleted();
realm.close();
}
});
}
});
}
}
});
In this case onChange is never called, exception being thrown java.lang.IllegalStateException: You can't register a listener from a non-Looper thread or IntentService thread. If I change Scheduler from subscribeOn to AndroidSchedulers.mainThread onCalled
@dzakens It would be easier to debug this if you created a sample project demonstrating the problem. Trying to debug code snippets is rather difficult and error prone.
@dzakens Did you solve the issue? Or can you help us by creating a sample project?
@dzakens Please reopen or create a new issue if you can take the time to create a sample project.
My goal is to have many to many relationship within same class in Realm. I tried to add object to RealmList in this way :
When I try to fetch all DeviceEntity objects stored in realm like this :
For all DeviceEntity objects getConnectedDevices() return null
How should I fetch connectedDevices ?