Room - Delete executes after I insert new values
I'm studying Rxjava2 and I'm trying to integrate the Room Library with Rxjava2. The problem is: I have a populated table and every time I login in the app, I need to delete this table and then insert a new content in database. Separately, the delete and insert works fine, but when I try to insert new values after I delete the table content, the delete method deletes all the new values.. (some parts of the code is in kotlin and others in java)
I already tried this: RxJava2 + Room: data is not being inserted in DB after clearAllTables() call, but no success..
DAO
@Dao
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(list:List<Something>)
@Query("DELETE FROM SomethingTable")
fun delete()
@Query("SELECT * FROM SomethingTable")
fun getAll(): Flowable<List<Something>>
My class that calls the DAO (CallDao)
//insert
fun insertInDB(list: List<Something>) {
Completable.fromAction {
dbDAO!!.insert(list)
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe()
}
//delete
fun clean() {
Completable.fromAction {
dbDAO!!.delete()
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe()
}
//search all
fun findAll(): Observable<List<Something>>? {
return Observable.create { subscriber ->
dbDAO!!.getAll()
.subscribeOn(Schedulers.io())
.subscribe {it->
subscriber.onNext(it)
}
}
}
Method that is called when I click in login button
private void clearAndInsertInDB() {
CallDao callDao= new CallDao(getActivity());
//delete all table values
callDao.clean();
Something sm = new Something("test1", "test2");
ArrayList<Something> list = new ArrayList<>();
list.add(sm);
list.add(sm);
//insert new values
callDao.insertInDB(list);
//get all new values in DB
callDao.findAll()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(res -> {
//here gives me a IndexOutOfBoundsException
Log.d("logDebug", res.get(0).getCodeExemple());
});
}
Any corrections in my code is also welcome :) , but the main problem is that the delete method deletes all the new insert values and it should delete only the old values.
android kotlin rx-java2 android-room
add a comment |
I'm studying Rxjava2 and I'm trying to integrate the Room Library with Rxjava2. The problem is: I have a populated table and every time I login in the app, I need to delete this table and then insert a new content in database. Separately, the delete and insert works fine, but when I try to insert new values after I delete the table content, the delete method deletes all the new values.. (some parts of the code is in kotlin and others in java)
I already tried this: RxJava2 + Room: data is not being inserted in DB after clearAllTables() call, but no success..
DAO
@Dao
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(list:List<Something>)
@Query("DELETE FROM SomethingTable")
fun delete()
@Query("SELECT * FROM SomethingTable")
fun getAll(): Flowable<List<Something>>
My class that calls the DAO (CallDao)
//insert
fun insertInDB(list: List<Something>) {
Completable.fromAction {
dbDAO!!.insert(list)
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe()
}
//delete
fun clean() {
Completable.fromAction {
dbDAO!!.delete()
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe()
}
//search all
fun findAll(): Observable<List<Something>>? {
return Observable.create { subscriber ->
dbDAO!!.getAll()
.subscribeOn(Schedulers.io())
.subscribe {it->
subscriber.onNext(it)
}
}
}
Method that is called when I click in login button
private void clearAndInsertInDB() {
CallDao callDao= new CallDao(getActivity());
//delete all table values
callDao.clean();
Something sm = new Something("test1", "test2");
ArrayList<Something> list = new ArrayList<>();
list.add(sm);
list.add(sm);
//insert new values
callDao.insertInDB(list);
//get all new values in DB
callDao.findAll()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(res -> {
//here gives me a IndexOutOfBoundsException
Log.d("logDebug", res.get(0).getCodeExemple());
});
}
Any corrections in my code is also welcome :) , but the main problem is that the delete method deletes all the new insert values and it should delete only the old values.
android kotlin rx-java2 android-room
Instead of using Query use @Delete annotation to delete a single item and pass the Item object as a parameter
– deepak kumar
Nov 16 '18 at 19:54
@deepakkumar, I want to delete all table content and not a single item..
– barbs
Nov 16 '18 at 19:55
Sorry, I misunderstood but what's your real problem dele executing after insert or delete method deletes all tge new values??
– deepak kumar
Nov 16 '18 at 20:01
my problem is: the delete method is being called before I insert the new values, but it is executing after I insert the new values.
– barbs
Nov 16 '18 at 20:05
May be it's because of schedules but you can avoid this by waiting for the operation to complete using await method like in the Kotlin Coroutines await for async to complete.
– deepak kumar
Nov 16 '18 at 20:15
add a comment |
I'm studying Rxjava2 and I'm trying to integrate the Room Library with Rxjava2. The problem is: I have a populated table and every time I login in the app, I need to delete this table and then insert a new content in database. Separately, the delete and insert works fine, but when I try to insert new values after I delete the table content, the delete method deletes all the new values.. (some parts of the code is in kotlin and others in java)
I already tried this: RxJava2 + Room: data is not being inserted in DB after clearAllTables() call, but no success..
DAO
@Dao
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(list:List<Something>)
@Query("DELETE FROM SomethingTable")
fun delete()
@Query("SELECT * FROM SomethingTable")
fun getAll(): Flowable<List<Something>>
My class that calls the DAO (CallDao)
//insert
fun insertInDB(list: List<Something>) {
Completable.fromAction {
dbDAO!!.insert(list)
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe()
}
//delete
fun clean() {
Completable.fromAction {
dbDAO!!.delete()
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe()
}
//search all
fun findAll(): Observable<List<Something>>? {
return Observable.create { subscriber ->
dbDAO!!.getAll()
.subscribeOn(Schedulers.io())
.subscribe {it->
subscriber.onNext(it)
}
}
}
Method that is called when I click in login button
private void clearAndInsertInDB() {
CallDao callDao= new CallDao(getActivity());
//delete all table values
callDao.clean();
Something sm = new Something("test1", "test2");
ArrayList<Something> list = new ArrayList<>();
list.add(sm);
list.add(sm);
//insert new values
callDao.insertInDB(list);
//get all new values in DB
callDao.findAll()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(res -> {
//here gives me a IndexOutOfBoundsException
Log.d("logDebug", res.get(0).getCodeExemple());
});
}
Any corrections in my code is also welcome :) , but the main problem is that the delete method deletes all the new insert values and it should delete only the old values.
android kotlin rx-java2 android-room
I'm studying Rxjava2 and I'm trying to integrate the Room Library with Rxjava2. The problem is: I have a populated table and every time I login in the app, I need to delete this table and then insert a new content in database. Separately, the delete and insert works fine, but when I try to insert new values after I delete the table content, the delete method deletes all the new values.. (some parts of the code is in kotlin and others in java)
I already tried this: RxJava2 + Room: data is not being inserted in DB after clearAllTables() call, but no success..
DAO
@Dao
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(list:List<Something>)
@Query("DELETE FROM SomethingTable")
fun delete()
@Query("SELECT * FROM SomethingTable")
fun getAll(): Flowable<List<Something>>
My class that calls the DAO (CallDao)
//insert
fun insertInDB(list: List<Something>) {
Completable.fromAction {
dbDAO!!.insert(list)
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe()
}
//delete
fun clean() {
Completable.fromAction {
dbDAO!!.delete()
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe()
}
//search all
fun findAll(): Observable<List<Something>>? {
return Observable.create { subscriber ->
dbDAO!!.getAll()
.subscribeOn(Schedulers.io())
.subscribe {it->
subscriber.onNext(it)
}
}
}
Method that is called when I click in login button
private void clearAndInsertInDB() {
CallDao callDao= new CallDao(getActivity());
//delete all table values
callDao.clean();
Something sm = new Something("test1", "test2");
ArrayList<Something> list = new ArrayList<>();
list.add(sm);
list.add(sm);
//insert new values
callDao.insertInDB(list);
//get all new values in DB
callDao.findAll()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(res -> {
//here gives me a IndexOutOfBoundsException
Log.d("logDebug", res.get(0).getCodeExemple());
});
}
Any corrections in my code is also welcome :) , but the main problem is that the delete method deletes all the new insert values and it should delete only the old values.
android kotlin rx-java2 android-room
android kotlin rx-java2 android-room
edited Nov 16 '18 at 20:07
barbs
asked Nov 16 '18 at 19:49
barbsbarbs
525
525
Instead of using Query use @Delete annotation to delete a single item and pass the Item object as a parameter
– deepak kumar
Nov 16 '18 at 19:54
@deepakkumar, I want to delete all table content and not a single item..
– barbs
Nov 16 '18 at 19:55
Sorry, I misunderstood but what's your real problem dele executing after insert or delete method deletes all tge new values??
– deepak kumar
Nov 16 '18 at 20:01
my problem is: the delete method is being called before I insert the new values, but it is executing after I insert the new values.
– barbs
Nov 16 '18 at 20:05
May be it's because of schedules but you can avoid this by waiting for the operation to complete using await method like in the Kotlin Coroutines await for async to complete.
– deepak kumar
Nov 16 '18 at 20:15
add a comment |
Instead of using Query use @Delete annotation to delete a single item and pass the Item object as a parameter
– deepak kumar
Nov 16 '18 at 19:54
@deepakkumar, I want to delete all table content and not a single item..
– barbs
Nov 16 '18 at 19:55
Sorry, I misunderstood but what's your real problem dele executing after insert or delete method deletes all tge new values??
– deepak kumar
Nov 16 '18 at 20:01
my problem is: the delete method is being called before I insert the new values, but it is executing after I insert the new values.
– barbs
Nov 16 '18 at 20:05
May be it's because of schedules but you can avoid this by waiting for the operation to complete using await method like in the Kotlin Coroutines await for async to complete.
– deepak kumar
Nov 16 '18 at 20:15
Instead of using Query use @Delete annotation to delete a single item and pass the Item object as a parameter
– deepak kumar
Nov 16 '18 at 19:54
Instead of using Query use @Delete annotation to delete a single item and pass the Item object as a parameter
– deepak kumar
Nov 16 '18 at 19:54
@deepakkumar, I want to delete all table content and not a single item..
– barbs
Nov 16 '18 at 19:55
@deepakkumar, I want to delete all table content and not a single item..
– barbs
Nov 16 '18 at 19:55
Sorry, I misunderstood but what's your real problem dele executing after insert or delete method deletes all tge new values??
– deepak kumar
Nov 16 '18 at 20:01
Sorry, I misunderstood but what's your real problem dele executing after insert or delete method deletes all tge new values??
– deepak kumar
Nov 16 '18 at 20:01
my problem is: the delete method is being called before I insert the new values, but it is executing after I insert the new values.
– barbs
Nov 16 '18 at 20:05
my problem is: the delete method is being called before I insert the new values, but it is executing after I insert the new values.
– barbs
Nov 16 '18 at 20:05
May be it's because of schedules but you can avoid this by waiting for the operation to complete using await method like in the Kotlin Coroutines await for async to complete.
– deepak kumar
Nov 16 '18 at 20:15
May be it's because of schedules but you can avoid this by waiting for the operation to complete using await method like in the Kotlin Coroutines await for async to complete.
– deepak kumar
Nov 16 '18 at 20:15
add a comment |
2 Answers
2
active
oldest
votes
You are making two asynchronous calls: one to delete the users and another to insert them. However, even though you call first the callDao.clean();
method and after that you call callDao.insertInDB(list);
, it is not guaranteed that the clean operation will be executed before the insert operation (because that's how asynchronous calls work).
This is what is happening:
Instead, you should chain your async calls , in such a way that the second one gets call as soon as you know that the first one has already finished.
How to achieve that using RxJava? Using andThen
operator as stated in this answer
You should modify your clean
and insert
methods to return the Completables, use andThen
to chain them, and then subscribe.
Simple example using RxJava and andThen()
FakeDatabase db = Room.databaseBuilder(this, FakeDatabase.class, "fake.db")
.fallbackToDestructiveMigration()
.build();
UserDao userDao = db.userDao();
User user1 = new User("Diego", "Garcia Lozano", "diegogarcialozano@fake.com");
User user2 = new User("Juan", "Perez", "juanperez@fake.com");
User user3 = new User("Pedro", "Lopez", "pedrolopez@fake.com");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
Completable deleteAllCompletable = Completable.fromAction(userDao::deleteAll);
Completable insertUserCompletable = Completable.fromAction(() -> userDao.insertAll(users));
deleteAllCompletable
.andThen(Completable.fromAction(() -> System.out.println("Delete finished")))
.andThen(insertUserCompletable)
.andThen(Completable.fromAction(() -> System.out.println("Insert finished")))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the Logcat after execution, you can see that the operations were executed in the proper order:
2018-11-19 16:07:02.056 10029-10047/? I/System.out: Delete finished
2018-11-19 16:07:02.060 10029-10047/? I/System.out: Insert finished
And then I checked the content of the database using the tool SQLite Browser and saw that the insert worked properly.
Using @Transaction in the DAO
You can also try to get a solution to your problem without using RxJava. Instead, you can define a Transaction in your DAO using the @Transaction operation, as explained in this post. It would look something like this:
Dao
@Dao
public abstract class UserDao {
@Transaction
public void deleteAndCreate(List<User> users) {
deleteAll();
insertAll(users);
}
@Query("DELETE FROM User")
public abstract void deleteAll();
@Insert
public abstract void insertAll(List<User> users);
}
Activity
Completable.fromAction(() -> userDao.deleteAndCreate(users))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the table
Personally, I would do it with the @Transaction annotation.
Thanks for your help! I didn't check as a correct answer, because I'm still trying to use Future and Completables like you said, and it's kind difficult :(
– barbs
Nov 19 '18 at 11:56
Please, check my updated answer. I would use the @Transaction annotation. Cheers
– dglozano
Nov 19 '18 at 19:42
1
Thanks a lot!! It's working now!! :)
– barbs
Nov 20 '18 at 17:50
add a comment |
So do You have any values left after pressing the button?
I am not yet able to comment so I am asking here, sorry for that
No, I don't have any values. The delete method is being call after the insert method, and it should be the opposite.. it's like dglozano said, the problem is the async calls and I need them to be sync
– barbs
Nov 18 '18 at 1:33
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53344456%2froom-delete-executes-after-i-insert-new-values%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You are making two asynchronous calls: one to delete the users and another to insert them. However, even though you call first the callDao.clean();
method and after that you call callDao.insertInDB(list);
, it is not guaranteed that the clean operation will be executed before the insert operation (because that's how asynchronous calls work).
This is what is happening:
Instead, you should chain your async calls , in such a way that the second one gets call as soon as you know that the first one has already finished.
How to achieve that using RxJava? Using andThen
operator as stated in this answer
You should modify your clean
and insert
methods to return the Completables, use andThen
to chain them, and then subscribe.
Simple example using RxJava and andThen()
FakeDatabase db = Room.databaseBuilder(this, FakeDatabase.class, "fake.db")
.fallbackToDestructiveMigration()
.build();
UserDao userDao = db.userDao();
User user1 = new User("Diego", "Garcia Lozano", "diegogarcialozano@fake.com");
User user2 = new User("Juan", "Perez", "juanperez@fake.com");
User user3 = new User("Pedro", "Lopez", "pedrolopez@fake.com");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
Completable deleteAllCompletable = Completable.fromAction(userDao::deleteAll);
Completable insertUserCompletable = Completable.fromAction(() -> userDao.insertAll(users));
deleteAllCompletable
.andThen(Completable.fromAction(() -> System.out.println("Delete finished")))
.andThen(insertUserCompletable)
.andThen(Completable.fromAction(() -> System.out.println("Insert finished")))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the Logcat after execution, you can see that the operations were executed in the proper order:
2018-11-19 16:07:02.056 10029-10047/? I/System.out: Delete finished
2018-11-19 16:07:02.060 10029-10047/? I/System.out: Insert finished
And then I checked the content of the database using the tool SQLite Browser and saw that the insert worked properly.
Using @Transaction in the DAO
You can also try to get a solution to your problem without using RxJava. Instead, you can define a Transaction in your DAO using the @Transaction operation, as explained in this post. It would look something like this:
Dao
@Dao
public abstract class UserDao {
@Transaction
public void deleteAndCreate(List<User> users) {
deleteAll();
insertAll(users);
}
@Query("DELETE FROM User")
public abstract void deleteAll();
@Insert
public abstract void insertAll(List<User> users);
}
Activity
Completable.fromAction(() -> userDao.deleteAndCreate(users))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the table
Personally, I would do it with the @Transaction annotation.
Thanks for your help! I didn't check as a correct answer, because I'm still trying to use Future and Completables like you said, and it's kind difficult :(
– barbs
Nov 19 '18 at 11:56
Please, check my updated answer. I would use the @Transaction annotation. Cheers
– dglozano
Nov 19 '18 at 19:42
1
Thanks a lot!! It's working now!! :)
– barbs
Nov 20 '18 at 17:50
add a comment |
You are making two asynchronous calls: one to delete the users and another to insert them. However, even though you call first the callDao.clean();
method and after that you call callDao.insertInDB(list);
, it is not guaranteed that the clean operation will be executed before the insert operation (because that's how asynchronous calls work).
This is what is happening:
Instead, you should chain your async calls , in such a way that the second one gets call as soon as you know that the first one has already finished.
How to achieve that using RxJava? Using andThen
operator as stated in this answer
You should modify your clean
and insert
methods to return the Completables, use andThen
to chain them, and then subscribe.
Simple example using RxJava and andThen()
FakeDatabase db = Room.databaseBuilder(this, FakeDatabase.class, "fake.db")
.fallbackToDestructiveMigration()
.build();
UserDao userDao = db.userDao();
User user1 = new User("Diego", "Garcia Lozano", "diegogarcialozano@fake.com");
User user2 = new User("Juan", "Perez", "juanperez@fake.com");
User user3 = new User("Pedro", "Lopez", "pedrolopez@fake.com");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
Completable deleteAllCompletable = Completable.fromAction(userDao::deleteAll);
Completable insertUserCompletable = Completable.fromAction(() -> userDao.insertAll(users));
deleteAllCompletable
.andThen(Completable.fromAction(() -> System.out.println("Delete finished")))
.andThen(insertUserCompletable)
.andThen(Completable.fromAction(() -> System.out.println("Insert finished")))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the Logcat after execution, you can see that the operations were executed in the proper order:
2018-11-19 16:07:02.056 10029-10047/? I/System.out: Delete finished
2018-11-19 16:07:02.060 10029-10047/? I/System.out: Insert finished
And then I checked the content of the database using the tool SQLite Browser and saw that the insert worked properly.
Using @Transaction in the DAO
You can also try to get a solution to your problem without using RxJava. Instead, you can define a Transaction in your DAO using the @Transaction operation, as explained in this post. It would look something like this:
Dao
@Dao
public abstract class UserDao {
@Transaction
public void deleteAndCreate(List<User> users) {
deleteAll();
insertAll(users);
}
@Query("DELETE FROM User")
public abstract void deleteAll();
@Insert
public abstract void insertAll(List<User> users);
}
Activity
Completable.fromAction(() -> userDao.deleteAndCreate(users))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the table
Personally, I would do it with the @Transaction annotation.
Thanks for your help! I didn't check as a correct answer, because I'm still trying to use Future and Completables like you said, and it's kind difficult :(
– barbs
Nov 19 '18 at 11:56
Please, check my updated answer. I would use the @Transaction annotation. Cheers
– dglozano
Nov 19 '18 at 19:42
1
Thanks a lot!! It's working now!! :)
– barbs
Nov 20 '18 at 17:50
add a comment |
You are making two asynchronous calls: one to delete the users and another to insert them. However, even though you call first the callDao.clean();
method and after that you call callDao.insertInDB(list);
, it is not guaranteed that the clean operation will be executed before the insert operation (because that's how asynchronous calls work).
This is what is happening:
Instead, you should chain your async calls , in such a way that the second one gets call as soon as you know that the first one has already finished.
How to achieve that using RxJava? Using andThen
operator as stated in this answer
You should modify your clean
and insert
methods to return the Completables, use andThen
to chain them, and then subscribe.
Simple example using RxJava and andThen()
FakeDatabase db = Room.databaseBuilder(this, FakeDatabase.class, "fake.db")
.fallbackToDestructiveMigration()
.build();
UserDao userDao = db.userDao();
User user1 = new User("Diego", "Garcia Lozano", "diegogarcialozano@fake.com");
User user2 = new User("Juan", "Perez", "juanperez@fake.com");
User user3 = new User("Pedro", "Lopez", "pedrolopez@fake.com");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
Completable deleteAllCompletable = Completable.fromAction(userDao::deleteAll);
Completable insertUserCompletable = Completable.fromAction(() -> userDao.insertAll(users));
deleteAllCompletable
.andThen(Completable.fromAction(() -> System.out.println("Delete finished")))
.andThen(insertUserCompletable)
.andThen(Completable.fromAction(() -> System.out.println("Insert finished")))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the Logcat after execution, you can see that the operations were executed in the proper order:
2018-11-19 16:07:02.056 10029-10047/? I/System.out: Delete finished
2018-11-19 16:07:02.060 10029-10047/? I/System.out: Insert finished
And then I checked the content of the database using the tool SQLite Browser and saw that the insert worked properly.
Using @Transaction in the DAO
You can also try to get a solution to your problem without using RxJava. Instead, you can define a Transaction in your DAO using the @Transaction operation, as explained in this post. It would look something like this:
Dao
@Dao
public abstract class UserDao {
@Transaction
public void deleteAndCreate(List<User> users) {
deleteAll();
insertAll(users);
}
@Query("DELETE FROM User")
public abstract void deleteAll();
@Insert
public abstract void insertAll(List<User> users);
}
Activity
Completable.fromAction(() -> userDao.deleteAndCreate(users))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the table
Personally, I would do it with the @Transaction annotation.
You are making two asynchronous calls: one to delete the users and another to insert them. However, even though you call first the callDao.clean();
method and after that you call callDao.insertInDB(list);
, it is not guaranteed that the clean operation will be executed before the insert operation (because that's how asynchronous calls work).
This is what is happening:
Instead, you should chain your async calls , in such a way that the second one gets call as soon as you know that the first one has already finished.
How to achieve that using RxJava? Using andThen
operator as stated in this answer
You should modify your clean
and insert
methods to return the Completables, use andThen
to chain them, and then subscribe.
Simple example using RxJava and andThen()
FakeDatabase db = Room.databaseBuilder(this, FakeDatabase.class, "fake.db")
.fallbackToDestructiveMigration()
.build();
UserDao userDao = db.userDao();
User user1 = new User("Diego", "Garcia Lozano", "diegogarcialozano@fake.com");
User user2 = new User("Juan", "Perez", "juanperez@fake.com");
User user3 = new User("Pedro", "Lopez", "pedrolopez@fake.com");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
Completable deleteAllCompletable = Completable.fromAction(userDao::deleteAll);
Completable insertUserCompletable = Completable.fromAction(() -> userDao.insertAll(users));
deleteAllCompletable
.andThen(Completable.fromAction(() -> System.out.println("Delete finished")))
.andThen(insertUserCompletable)
.andThen(Completable.fromAction(() -> System.out.println("Insert finished")))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the Logcat after execution, you can see that the operations were executed in the proper order:
2018-11-19 16:07:02.056 10029-10047/? I/System.out: Delete finished
2018-11-19 16:07:02.060 10029-10047/? I/System.out: Insert finished
And then I checked the content of the database using the tool SQLite Browser and saw that the insert worked properly.
Using @Transaction in the DAO
You can also try to get a solution to your problem without using RxJava. Instead, you can define a Transaction in your DAO using the @Transaction operation, as explained in this post. It would look something like this:
Dao
@Dao
public abstract class UserDao {
@Transaction
public void deleteAndCreate(List<User> users) {
deleteAll();
insertAll(users);
}
@Query("DELETE FROM User")
public abstract void deleteAll();
@Insert
public abstract void insertAll(List<User> users);
}
Activity
Completable.fromAction(() -> userDao.deleteAndCreate(users))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.single())
.subscribe();
Checking the table
Personally, I would do it with the @Transaction annotation.
edited Nov 19 '18 at 19:42
answered Nov 16 '18 at 21:54
dglozanodglozano
923120
923120
Thanks for your help! I didn't check as a correct answer, because I'm still trying to use Future and Completables like you said, and it's kind difficult :(
– barbs
Nov 19 '18 at 11:56
Please, check my updated answer. I would use the @Transaction annotation. Cheers
– dglozano
Nov 19 '18 at 19:42
1
Thanks a lot!! It's working now!! :)
– barbs
Nov 20 '18 at 17:50
add a comment |
Thanks for your help! I didn't check as a correct answer, because I'm still trying to use Future and Completables like you said, and it's kind difficult :(
– barbs
Nov 19 '18 at 11:56
Please, check my updated answer. I would use the @Transaction annotation. Cheers
– dglozano
Nov 19 '18 at 19:42
1
Thanks a lot!! It's working now!! :)
– barbs
Nov 20 '18 at 17:50
Thanks for your help! I didn't check as a correct answer, because I'm still trying to use Future and Completables like you said, and it's kind difficult :(
– barbs
Nov 19 '18 at 11:56
Thanks for your help! I didn't check as a correct answer, because I'm still trying to use Future and Completables like you said, and it's kind difficult :(
– barbs
Nov 19 '18 at 11:56
Please, check my updated answer. I would use the @Transaction annotation. Cheers
– dglozano
Nov 19 '18 at 19:42
Please, check my updated answer. I would use the @Transaction annotation. Cheers
– dglozano
Nov 19 '18 at 19:42
1
1
Thanks a lot!! It's working now!! :)
– barbs
Nov 20 '18 at 17:50
Thanks a lot!! It's working now!! :)
– barbs
Nov 20 '18 at 17:50
add a comment |
So do You have any values left after pressing the button?
I am not yet able to comment so I am asking here, sorry for that
No, I don't have any values. The delete method is being call after the insert method, and it should be the opposite.. it's like dglozano said, the problem is the async calls and I need them to be sync
– barbs
Nov 18 '18 at 1:33
add a comment |
So do You have any values left after pressing the button?
I am not yet able to comment so I am asking here, sorry for that
No, I don't have any values. The delete method is being call after the insert method, and it should be the opposite.. it's like dglozano said, the problem is the async calls and I need them to be sync
– barbs
Nov 18 '18 at 1:33
add a comment |
So do You have any values left after pressing the button?
I am not yet able to comment so I am asking here, sorry for that
So do You have any values left after pressing the button?
I am not yet able to comment so I am asking here, sorry for that
answered Nov 17 '18 at 0:10
DimnessDimness
120110
120110
No, I don't have any values. The delete method is being call after the insert method, and it should be the opposite.. it's like dglozano said, the problem is the async calls and I need them to be sync
– barbs
Nov 18 '18 at 1:33
add a comment |
No, I don't have any values. The delete method is being call after the insert method, and it should be the opposite.. it's like dglozano said, the problem is the async calls and I need them to be sync
– barbs
Nov 18 '18 at 1:33
No, I don't have any values. The delete method is being call after the insert method, and it should be the opposite.. it's like dglozano said, the problem is the async calls and I need them to be sync
– barbs
Nov 18 '18 at 1:33
No, I don't have any values. The delete method is being call after the insert method, and it should be the opposite.. it's like dglozano said, the problem is the async calls and I need them to be sync
– barbs
Nov 18 '18 at 1:33
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53344456%2froom-delete-executes-after-i-insert-new-values%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Instead of using Query use @Delete annotation to delete a single item and pass the Item object as a parameter
– deepak kumar
Nov 16 '18 at 19:54
@deepakkumar, I want to delete all table content and not a single item..
– barbs
Nov 16 '18 at 19:55
Sorry, I misunderstood but what's your real problem dele executing after insert or delete method deletes all tge new values??
– deepak kumar
Nov 16 '18 at 20:01
my problem is: the delete method is being called before I insert the new values, but it is executing after I insert the new values.
– barbs
Nov 16 '18 at 20:05
May be it's because of schedules but you can avoid this by waiting for the operation to complete using await method like in the Kotlin Coroutines await for async to complete.
– deepak kumar
Nov 16 '18 at 20:15