Android Room Test Delete Not Working (Java) - java

I'm trying to unit-test my DAO using android-room. I have written an insert test that works properly. Unfortunately, the delete method doesn't seem to be working.
I've tried a few different setups for the test. None have worked.
Here is the DAO:
#Dao
public interface MonthlyDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
void saveAll(List<Monthly> goals);
#Insert(onConflict = OnConflictStrategy.REPLACE)
void save(Monthly goal);
#Update
void update(Monthly goal);
#Delete
void delete(Monthly goal);
#Query("SELECT * FROM Monthly")
LiveData<List<Monthly>> findAll();
#Query("SELECT * FROM monthly")
List<Monthly> findAllList();
}
Here is the Monthly entity:
#Entity
public class Monthly {
#PrimaryKey(autoGenerate = true)
private int monthlyId;
#TypeConverters(CalendarTypeConverter.class)
#ColumnInfo(name = "date")
private Calendar date = Calendar.getInstance();
#ColumnInfo(name = "title")
private String title;
#ColumnInfo(name = "description")
private String description;
#ColumnInfo(name = "completed")
private boolean completed;
...
public int getMonthlyId() {
return monthlyId;
}
public void setMonthlyId(int monthlyId) {
this.monthlyId = monthlyId;
}
And here is the test I am running:
#RunWith(AndroidJUnit4.class)
public class MonthlyTest {
private MonthlyDao monthlyDao;
private MonthlyGoalsDatabase db;
#Before
public void createDb() {
Context context = ApplicationProvider.getApplicationContext();
db = Room.inMemoryDatabaseBuilder(context, MonthlyGoalsDatabase.class).build();
monthlyDao = db.getMonthlyDao();
}
#After
public void closeDb() throws IOException {
db.close();
}
#Test
public void deleteGoal() throws Exception {
String title = "test delete title";
Calendar date = Calendar.getInstance();
date.set(Calendar.HOUR_OF_DAY, 0);
String desc = "test delete desc";
Monthly goal = new Monthly(title, date, desc);
monthlyDao.save(goal);
List<Monthly> goals = monthlyDao.findAllList();
Assert.assertThat(goals.get(0).getTitle(), equalTo(goal.getTitle()));
monthlyDao.delete(goal);
List<Monthly> updatedGoals = monthlyDao.findAllList();
Assert.assertTrue(updatedGoals.isEmpty());
}
I except the updatedGoals list to be empty, but it isn't. There is still the goal that I inserted during the test.

The method annotated with #Delete uses the primary key on the entity to know which row to delete from the database (because there could be multiple rows with the same data but different keys).
However, you're using the initial goal object that you created, which has no primary key, and thus cannot be used to indicate which row to remove.
Try doing this:
monthlyDao.save(goal);
List<Monthly> goals = monthlyDao.findAllList();
Assert.assertThat(goals.get(0).getTitle(), equalTo(goal.getTitle()));
monthlyDao.delete(goals.get(0)); // <-- Delete the goal returned from the find, which will have an ID
List<Monthly> updatedGoals = monthlyDao.findAllList();
Assert.assertTrue(updatedGoals.isEmpty());
That could easily be cleaned up a bit, but the above example only changes one line, to make it clear where the issue is.
See here for the relevant documentation.

Related

Why instrumented room test get error FOREIGN KEY constraint failed

I don't understand this error, I have two entities Task and Project, one task is assign to one project (see code below).
But when I want test to add a task, I have this error:
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
I try to add onDelete = CASCADE to FOREIGNKEY but my test does not work :/
Task Class
#Entity(tableName = "task_table",
foreignKeys = #ForeignKey(entity = Project.class,
parentColumns = "id",
childColumns = "projectId"))
public class Task {
/**
* The unique identifier of the task
*/
#PrimaryKey(autoGenerate = true)
public long id;
private long projectId;
#SuppressWarnings("NullableProblems")
#NonNull
private String name.
private long creationTimestamp;
public Task(long projectId, #NonNull String name, long creationTimestamp) {
this.setProjectId(projectId);
this.setName(name);
this.setCreationTimestamp(creationTimestamp);
}
...
TaskDao
#Dao
public interface TaskDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Task task);
#Query("DELETE FROM task_table WHERE id = :id")
void delete(long id);
#Query("SELECT * FROM task_table ORDER BY id ASC")
LiveData<List<Task>> getAllTasks();
#Query("SELECT * FROM task_table WHERE id = :id")
LiveData<Task> getTaskById(long id);
}
Project Class
#Entity(tableName = "project_table")
public class Project {
/**
* The unique identifier of the project
*/
#PrimaryKey(autoGenerate = true)
public long id;
#NonNull
private String name;
#ColorInt
private int color;
public Project(#NonNull String name, #ColorInt int color) {
this.name = name;
this.color = color;
}
ProjectDao
#Dao
public interface ProjectDao {
#Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(Project project);
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(List<Project> projects);
#Query("SELECT * FROM project_table")
LiveData<List<Project>> getAllProjects();
#Query("SELECT * FROM project_table WHERE id = :id")
LiveData<Project> getProjectById(long id);
}
TestInstrumented:
#Before
public void createDb() {
this.database = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(),
AppDatabase.class)
.allowMainThreadQueries()
.build();
taskDao = database.taskDao();
projectDao = database.projectDao();
}
#After
public void closeDb() {
database.close();
}
#Test
public void addTask() {
Project project = new Project("toto", 0xFFB4CDBA);
this.projectDao.insert(project);
long projectId = project.getId();
assertThat(projectId, equalTo(project.getId()));
Task task = new Task(projectId, "tâche 1", new Date().getTime());
this.taskDao.insert(task);
}
If someone can help it'll be very kind, I don't know how I can resolve this.
Thanks very much for your help
The project id will be 0 as it hasn't been set according to the inserted value when you use long projectId = project.getId();.
Thus the ForeignKey conflict when inserting the Task as the id column of the project will have been generated by SQLite and WILL not be 0 (it will be 1 or greater).
Change
#Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(Project project);
to (to get the actual generated id)
#Insert(onConflict = OnConflictStrategy.IGNORE)
long insert(Project project); // will return the id that has been generated
and then use :-
Project project = new Project("toto", 0xFFB4CDBA);
long projectId = this.projectDao.insert(project); //<<<<< returns the actual id
project.setId(projectId); // sets project id according to the inserted id BUT only if inserted and not ignored when returned value will be -1
// You should really check for -1 and handle accordingly
assertThat(projectId, equalTo(project.getId())); // not really of any use
Task task = new Task(projectId, "tâche 1", new Date().getTime());
this.taskDao.insert(task);
Note, the above is in-principle code, it has not been compiled or run/tested. It may therefore contain some errors.

How to migrate a Room database adding a Date column?

I have a simple database, with one table (id, title and description), I want to add a column to storage a duedate. I use the info I found in Developer android migration and TypeConverters to migrate it, I can install to test, but it doesn't open the app.
I'll apreciate any help!
My entity
#Entity(tableName = "todo_db")
public class todoEnt {
#PrimaryKey(autoGenerate = true)
public int id;
#ColumnInfo(name = "title")
public String todoTitle;
#ColumnInfo(name = "description")
public String todoDescription;
#ColumnInfo(name = "dueDate")
public Date dueDate;
}
I have a Typeconverter
public class Convertors {
#TypeConverter
public static Date fromTimeStamp(Long value){
return value == null ? null : new Date(value);
}
#TypeConverter
public static Long dateToTimestamp(Date date){
if (date == null) {
return null;
} else {
return date.getTime();
}
}
}
And I added this to my database file
#TypeConverters({Convertors.class})
static final Migration M_1_2 = new Migration(1, 2) {
#Override
public void migrate(#NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE todo_db ADD duedate INTEGER");
}
};
INSTANCE = Room.databaseBuilder(
context.getApplicationContext(),
TDAHdb.class,
"tdah_database")
.addMigrations(M_1_2)
.allowMainThreadQueries()
.build();
With Room migrations, table and column names are case-sensitive. Change duedate in your migration to match the case of the #ColumnInfo name specified in the entity definition, dueDate:
database.execSQL("ALTER TABLE todo_db ADD dueDate INTEGER");

Cannot use save() to insert when previously importing data using data.sql

I'm terribly sorry if I can't start another post which is connected to my previous one but my question is somewhat different.
I noticed that I really can save new data in my database as long as I never added data to the database by using the line spring.datasource.initialization-mode=always in my application.properties and made a data.sql file with a few insert statements. Once I insert the data using that file, I can access the data and show it to the user, but I can't create any new data because I get the following error
ERROR: duplicate key value violates unique constraint "joke_pkey"
Detail: Key (id)=(1) already exists.
Does anyone know how to help me with this? I'm doing an interview task and I am meant to first import data using the data.sql file and then later add some more data.
The post with my code is here:
Spring Boot using save never inserts a row inside of a Postgresql table
EDIT - someone recommended adding my code here directly and saying what I've tried.
I have tried to initialize the database with the application properties the way they are, then restarting the app but without the last line, and setting the spring.jpa.hibernate.ddl-auto to none. But even so, it didn't work. I genuinely expected it to work like that. Because if the table is empty and I fill it in using the functions I created, everything works like a charm, even after restarting the server (id keep the ring.jpa.hibernate.ddl-auto to none again to keep the data from being deleted)
I have also tried simply changing the GenerationType.AUTO to GenerationType.TABLE strategy in my Joke class, but that didn't seem to change anything either.
application.properties :
spring.datasource.url=jdbc:postgresql://localhost:5432/flyway_demo
spring.datasource.username=bob
spring.datasource.password=bob123
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create
spring.datasource.initialization-mode=always
My Web Controller that has the post function:
#PostMapping("/post")
public String insertJoke(JokeForm jokeForm) {
int categoryid = jokeForm.getCategoryId();
String content = jokeForm.getContent();
databasController.insert(categoryid, content);
return "redirect:/";
}
My DBController whose insert function is being called
public Joke insert(int categoryid, String content) {
return jokeRepository.save(new Joke(categoryid, content));
}
Most of my Joke data class:
#Entity
public class Joke {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(columnDefinition = "serial")
private Long id;
#NotNull
#Column(name = "category_id_FK")
private long categoryId;
#NotBlank
private String content;
#Column(columnDefinition = "integer default 0")
private int likes = 0;
#Column(columnDefinition = "integer default 0")
private int dislikes = 0;
public Joke() {
}
public Joke(long categoryid, String content) {
this.setCategoryid(categoryid);
this.setContent(content);
}
// id
public Long getId() {
return this.id;
}
// id
public void setId(Long id) {
this.id = id;
}
// categoryid
public long getCategoryid() {
return this.categoryId;
}
public void setCategoryid(long categoryid) {
this.categoryId = categoryid;
}
// content
public String getContent() {
return this.content;
}
public void setContent(String content) {
this.content = content;
}
// likes
public int getLikes() {
return this.likes;
}
public void setLikes(int likes) {
this.likes = likes;
}
// dislikes
public int getDislikes() {
return this.dislikes;
}
public void setDislikes(int dislikes) {
this.dislikes = dislikes;
}
}
Joke Repository:
#Repository
public interface JokeRepository extends JpaRepository<Joke, Integer> {
Joke findById(long id);
List<Joke> findByCategoryid(int categoryid);
}
It seems that all you need to do is change GenerationType.AUTO to GenerationType.IDENTITY.
Reason behind this is the sequence, which might be out of sync if you use AUTO. Because then hibernate uses its own sequence instead of the one postgres creates when using serial.

How to implement Server-side processing of DataTables with JDBC so that it paginates?

I have a Spring Boot app with DataTables server-side processing and Oracle database. Actually, I started with implementing one of the tutorials. It worked. The tutorial uses JPA. I want to implement the same using JDBC. I made all the corresponding classes, the repository, the new model with same filds but without jpa. But when I tried to fetch the data, it allowed me to get only the first page without a chance to get to the second page. Below I will post the extracts of the original and added code. So, the original tutorial used these classes:
#Entity
#Table(name = "MYUSERS")
public class User {
#Id
#Column(name = "USER_ID")
private Long id;
#Column(name = "USER_NAME")
private String name;
#Column(name = "SALARY")
private String salary;
...getters and setters
}
And
#Entity
public class UserModel {
#Id
private Long id;
private String name;
private String salary;
private Integer totalRecords;
#Transient
private Integer rn;
...getters and setters
}
And I substituted these two classes with one like this:
public class NewUser {
private Long id;
private String name;
private String salary;
private Integer totalRecords;
private Integer rn;
...getters and setters
}
The table itself has only 3 fields: id, name and salary, the other 2 fields are created and filled later.
The repositiry the original Author has for the user looks like this:
public interface UserRepository extends JpaRepository<User, Long> {
#Query(value = "SELECT * FROM MYUSERS", nativeQuery = true)
List<User> findAllByUsernames(List<String> listOfUsernames);
}
My own repository looks like this:
#Repository
public class NewUserRepoImpl extends JdbcDaoSupport implements NewUserRepo {
private static final String SELECT_ALL_SQL = "SELECT USER_ID as id, USER_NAME as name, SALARY as salary FROM MYUSERS";
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final JdbcTemplate jdbctemplate;
public NewUserRepoImpl(NamedParameterJdbcTemplate namedParameterJdbcTemplate, JdbcTemplate jdbctemplate, DataSource dataSource) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
this.jdbctemplate = jdbctemplate;
setDataSource(dataSource);
}
#Override
public List<NewUser> findAll(PaginationCriteria pagination) {
try {
String paginatedQuery = AppUtil.buildPaginatedQueryForOracle(SELECT_ALL_SQL, pagination);
return jdbctemplate.query(paginatedQuery, newUserRowMapper());
} catch (DataAccessException e) {
throw new EntityNotFoundException("No Entities Found");
}
}
#Bean
public RowMapper<NewUser> newUserRowMapper() {
return (rs, i) -> {
final NewUser newUser = new NewUser();
newUser.setId(rs.getLong("ID"));
newUser.setName(rs.getString("NAME"));
newUser.setSalary(rs.getString("SALARY"));
newUser.setTotalRecords(rs.getInt("TOTAL_RECORDS"));
newUser.setTotalRecords(rs.getInt("RN"));
return newUser;
};
}
}
the buildPaginatedQueryForOracle thing transforms my Query and allows it to get the totalRecords and rn. Below I will post the output of it both for the orifinal and my queries (they are the same, I checked).
So, the main part, the controller. I left the old and new pieces in it for now for debug purposes and just returning one of the results:
#RequestMapping(value="/users/paginated/orcl", method=RequestMethod.GET)
#ResponseBody
public String listUsersPaginatedForOracle(HttpServletRequest request, HttpServletResponse response, Model model) {
DataTableRequest<User> dataTableInRQ = new DataTableRequest<User>(request);
System.out.println(new Gson().toJson(dataTableInRQ));
DataTableRequest<NewUser> dataTableInRQNew = new DataTableRequest<NewUser>(request);
System.out.println(new Gson().toJson(dataTableInRQNew));
PaginationCriteria pagination = dataTableInRQ.getPaginationRequest();
System.out.println(new Gson().toJson(pagination));
PaginationCriteria paginationNew = dataTableInRQNew.getPaginationRequest();
System.out.println(new Gson().toJson(paginationNew));
String baseQuery = "SELECT USER_ID as id, USER_NAME as name, SALARY as salary FROM MYUSERS";
String paginatedQuery = AppUtil.buildPaginatedQueryForOracle(baseQuery, pagination);
String paginatedQueryNew = AppUtil.buildPaginatedQueryForOracle(baseQuery, paginationNew);
System.out.println(paginatedQuery);
System.out.println(paginatedQueryNew);
Query query = entityManager.createNativeQuery(paginatedQuery, UserModel.class);
System.out.println("Query:");
System.out.println(query);
#SuppressWarnings("unchecked")
List<UserModel> userList = query.getResultList();
System.out.println(new Gson().toJson(userList));
#SuppressWarnings("unchecked")
List<NewUser> userListNew = newUserRepo.findAll(paginationNew);
System.out.println(new Gson().toJson(userListNew));
DataTableResults<UserModel> dataTableResult = new DataTableResults<UserModel>();
DataTableResults<NewUser> dataTableResultNew = new DataTableResults<NewUser>();
dataTableResult.setDraw(dataTableInRQ.getDraw());
dataTableResultNew.setDraw(dataTableInRQNew.getDraw());
dataTableResult.setListOfDataObjects(userList);
dataTableResultNew.setListOfDataObjects(userListNew);
if (!AppUtil.isObjectEmpty(userList)) {
dataTableResult.setRecordsTotal(userList.get(0).getTotalRecords()
.toString());
if (dataTableInRQ.getPaginationRequest().isFilterByEmpty()) {
dataTableResult.setRecordsFiltered(userList.get(0).getTotalRecords()
.toString());
} else {
dataTableResult.setRecordsFiltered(Integer.toString(userList.size()));
}
}
if (!AppUtil.isObjectEmpty(userListNew)) {
dataTableResultNew.setRecordsTotal(userListNew.get(0).getTotalRecords()
.toString());
if (dataTableInRQ.getPaginationRequest().isFilterByEmpty()) {
dataTableResultNew.setRecordsFiltered(userListNew.get(0).getTotalRecords()
.toString());
} else {
dataTableResultNew.setRecordsFiltered(Integer.toString(userListNew.size()));
}
}
System.out.println(new Gson().toJson(dataTableResult));
System.out.println(new Gson().toJson(dataTableResultNew));
return new Gson().toJson(dataTableResult);
}
So, I log out everything possible in the console. Here is the output:
{"uniqueId":"1579786571491","draw":"1","start":0,"length":5,"search":"","regex":false,"columns":[{"index":0,"data":"id","name":"ID","searchable":true,"orderable":true,"search":"","regex":false,"sortDir":"ASC"},{"index":1,"data":"name","name":"Name","searchable":true,"orderable":true,"search":"","regex":false},{"index":2,"data":"salary","name":"Salary","searchable":true,"orderable":true,"search":"","regex":false}],"order":{"index":0,"data":"id","name":"ID","searchable":true,"orderable":true,"search":"","regex":false,"sortDir":"ASC"},"isGlobalSearch":false,"maxParamsToCheck":3}
{"uniqueId":"1579786571491","draw":"1","start":0,"length":5,"search":"","regex":false,"columns":[{"index":0,"data":"id","name":"ID","searchable":true,"orderable":true,"search":"","regex":false,"sortDir":"ASC"},{"index":1,"data":"name","name":"Name","searchable":true,"orderable":true,"search":"","regex":false},{"index":2,"data":"salary","name":"Salary","searchable":true,"orderable":true,"search":"","regex":false}],"order":{"index":0,"data":"id","name":"ID","searchable":true,"orderable":true,"search":"","regex":false,"sortDir":"ASC"},"isGlobalSearch":false,"maxParamsToCheck":3}
{"pageNumber":0,"pageSize":5,"sortBy":{"mapOfSorts":{"id":"ASC"}},"filterBy":{"mapOfFilters":{},"globalSearch":false}}
{"pageNumber":0,"pageSize":5,"sortBy":{"mapOfSorts":{"id":"ASC"}},"filterBy":{"mapOfFilters":{},"globalSearch":false}}
SELECT * FROM (SELECT FILTERED_ORDERED_RESULTS.*, COUNT(1) OVER() total_records, ROWNUM AS RN FROM (SELECT BASEINFO.* FROM ( SELECT USER_ID as id, USER_NAME as name, SALARY as salary FROM MYUSERS ) BASEINFO ) FILTERED_ORDERED_RESULTS ORDER BY id ASC ) WHERE RN > (0 * 5) AND RN <= (0 + 1) * 5
SELECT * FROM (SELECT FILTERED_ORDERED_RESULTS.*, COUNT(1) OVER() total_records, ROWNUM AS RN FROM (SELECT BASEINFO.* FROM ( SELECT USER_ID as id, USER_NAME as name, SALARY as salary FROM MYUSERS ) BASEINFO ) FILTERED_ORDERED_RESULTS ORDER BY id ASC ) WHERE RN > (0 * 5) AND RN <= (0 + 1) * 5
Query:
org.hibernate.query.internal.NativeQueryImpl#3ea49a4
[{"id":3,"name":"user3","salary":"300","totalRecords":18},{"id":4,"name":"user4","salary":"400","totalRecords":18},{"id":5,"name":"user5","salary":"500","totalRecords":18},{"id":6,"name":"user6","salary":"600","totalRecords":18},{"id":7,"name":"user7","salary":"700","totalRecords":18}]
[{"id":3,"name":"user3","salary":"300","totalRecords":1},{"id":4,"name":"user4","salary":"400","totalRecords":2},{"id":5,"name":"user5","salary":"500","totalRecords":3},{"id":6,"name":"user6","salary":"600","totalRecords":4},{"id":7,"name":"user7","salary":"700","totalRecords":5}]
{"draw":"1","recordsFiltered":"18","recordsTotal":"18","data":[{"id":3,"name":"user3","salary":"300","totalRecords":18},{"id":4,"name":"user4","salary":"400","totalRecords":18},{"id":5,"name":"user5","salary":"500","totalRecords":18},{"id":6,"name":"user6","salary":"600","totalRecords":18},{"id":7,"name":"user7","salary":"700","totalRecords":18}]}
{"draw":"1","recordsFiltered":"1","recordsTotal":"1","data":[{"id":3,"name":"user3","salary":"300","totalRecords":1},{"id":4,"name":"user4","salary":"400","totalRecords":2},{"id":5,"name":"user5","salary":"500","totalRecords":3},{"id":6,"name":"user6","salary":"600","totalRecords":4},{"id":7,"name":"user7","salary":"700","totalRecords":5}]}
It helped me realize that:
DataTableRequest incoming from the back is the same for both jpa
and jdbc
PaginationCriteria are also the same
paginatedQuery
having been made with the method specified above are the same.
Differences are already seen in the Lists: where the Jpa list
retrieved with native Query has totalRecords as 18 for every row,
the JDBC repo with the same query returns 1,2,3... for every
subsequent row.
It made me think that I should look at the Query made for JPA. But, as you see in the log, System.out.println wasn't able to decipher it for some reason.
Any advice on how to decipher it and more importantly how to get the right total result for each row would be greatly appreciated!!!

Room does not insert data to table

It is interesting point that it sometimes performs insert operation correctly. I do not know why and how this situation can be happens. So, I could not figure out where I made a mistake(s).
Here is my project files.
1) SentFilesDao.java
#Dao
public interface SentFilesDao {
#Query("SELECT id, name, type, status, dateTime FROM sent")
LiveData<List<SentFilesEntity>> getAllSentFiles();
#Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(SentFilesEntity file);
#Query("DELETE FROM sent")
void deleteAllRecords();
}
2) SentFilesRepository.java
public class SentFilesRepository {
private SentFilesDao mSentFilesDao;
private LiveData<List<SentFilesEntity>> mAllSentFiles;
SentFilesRepository(Application application) {
AppDatabase db = AppDatabase.getDatabase(application);
mSentFilesDao = db.mSentFilesDao();
mAllSentFiles = mSentFilesDao.getAllSentFiles();
}
LiveData<List<SentFilesEntity>> getAllSentFiles() { return mAllSentFiles; }
public void insert(SentFilesEntity sentFilesEntity) {
new SentFilesRepository.insertAsyncTask(mSentFilesDao).execute(sentFilesEntity);
}
private static class insertAsyncTask extends AsyncTask<SentFilesEntity, Void, Void> {
private SentFilesDao mAsyncTaskDao;
insertAsyncTask(SentFilesDao dao) {
mAsyncTaskDao = dao;
}
#Override
protected Void doInBackground(final SentFilesEntity... params) {
mAsyncTaskDao.insert(params[0]);
Log.e("doInBackground: ", "reached here!"); // no any log in Logcat about this. Weird...
return null;
}
}
}
3) SentFilesEntity.java
#Entity(tableName = "sent")
public class SentFilesEntity {
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "id")
public int s_f_id;
#ColumnInfo(name = "name")
public String s_f_name;
#ColumnInfo(name = "type")
public String s_f_type;
#ColumnInfo(name = "status")
public String s_f_operation_status;
#ColumnInfo(name = "dateTime")
public String s_f_time;
}
4) SentFilesViewModel.java
public class SentFilesViewModel extends AndroidViewModel {
private SentFilesRepository mRepository;
private LiveData<List<SentFilesEntity>> mAllSentFiles;
public SentFilesViewModel(Application application) {
super(application);
mRepository = new SentFilesRepository(application);
mAllSentFiles = mRepository.getAllSentFiles();
}
public LiveData<List<SentFilesEntity>> getAllSentFiles() { return mAllSentFiles; }
public void insert(SentFilesEntity sentFile) { mRepository.insert(sentFile); }
}
What I am trying to do:
My program sends selected files from one device to another one through WiFi Direct. As file received or sent, I want to save some information about file (such as file name, file type (image, video, music, APK and etc.), send/receive date and time) and operation (succeeded or failed). I can handle all these things.
What is the problem?
Well, getting all the properties (those I mentioned above), is not end. Main problem is saving that data to database. To do that I created some required files (I shared their codes above). When file sent, I am trying to insert related information to database. But it does not insert it. That is the my problem.
Well, main codes are too long to post here. However I posted my latest codes to my GitHub project and the main logic starts from here and it connected to FileStatisticsActivity.
p.s: Maybe sharing the project link is not ethic, I am so sorry for that.
Thanks.

Categories