I was trying to implement Room for persistent data storage in java. But I ran into problems with it.
In first try:
MyDao.java
@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void addUser(UserDetails userDetails);
}
MyDatabase.java
@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public abstract MyDao myDao();
}
with the above the app crashes with error:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
whenever I try to insert a data into the database.
In the second try:
MyDao.java
@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
ListenableFuture<Integer> addUser(UserDetails userDetails);
}
MyDatabase.java
@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public abstract MyDao myDao();
}
changed the return type to hold ListenableFuture<Integer>
because official doc says to do so.
The app does not build successfully and shows the following error:
error: Not sure how to handle insert method's return type.
So, my question is how can I correctly and successfully insert data in the database using room with java.
Please help.
After wandering on the internet for ages, I came to know that it is possible to write insert query using following 2 methods:
- Using a thread class
Operations.java
public class Operations{
private MyDao myDao;
public Operations(Context context){
MyDatabase db = Room.databaseBuilder(context, MyDatabase.class, "database")
.fallbackToDestructiveMigration()
.build();
myDao = db.myDao();
}
public void insertUser(UserDetails userDetails){
new Thread{
@override
public void run(){
myDao.addUser(userDetails);
}
}.start();
}
}
MyDao.java
@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void addUser(UserDetails userDetails);
}
MyDatabase.java
@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public abstract MyDao myDao();
}
- Using ExecutorService class
Operations.java
public class Operations{
private MyDao myDao;
public Operations(Context context){
MyDatabase db = Room.databaseBuilder(context, MyDatabase.class, "database")
.fallbackToDestructiveMigration()
.build();
myDao = db.myDao();
}
public void insertUser(UserDetails userDetails){
MyDatabase.databaseWriteExecutor.execute(()->{
notesDb.notesDao().addNote(note));
}
}
}
MyDao.java
@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void addUser(UserDetails userDetails);
}
MyDatabase.java
@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(2);
public abstract MyDao myDao();
}