I am developing an android app in Kotlin that stores and update student data. Each student has a unique ID and is stored as a primary key in the database. I was using SQLite at first but it was taking too much time to read the database when there is a lot of data. So am now trying to use Realm, I heard it's faster. The problem is, when I enter a primary key that is already in use it shows an error. I know it's supposed to happen. But then when I enter another key it says Cannot begin the write transaction: RealmCoreException([5]: The Realm is already in a write transaction)
. When I try again, the data is saved. But I want to cancel the transaction the exact moment the database encounters an error.
Below is the function to add the students
fun addStudent(mID: String, mName: String, mSex: Char) {
realm.writeBlocking {
this.copyToRealm(Student().apply {
_id = mID
name = mName
sex = mSex
})
}
}
Below is my onClickListener for the SAVE button
saveStudent.setOnClickListener {
val id = studentID.text.toString()
val name = studentName.text.toString().uppercase()
val sex: Char = studentSex!!
if (TextUtils.isEmpty(id)){
studentID.error = "ID cannot be empty"
studentID.requestFocus()
}else if (TextUtils.isEmpty(name)){
studentName.error = "Enter student name"
studentName.requestFocus()
}else if (TextUtils.isEmpty(sex.toString())){
Toast.makeText(context,"Please indicate whether male or female",Toast.LENGTH_SHORT).show()
}else {
kotlin.runCatching {
dbHelper.addStudent(id, name, sex)
}.onSuccess{
Toast.makeText(context,"$name was added!", Toast.LENGTH_SHORT).show()
Log.v("realm","$name was added!")
studentID.setText("")
studentName.setText("")
studentName.requestFocus()
getStudents()
}.onFailure {e ->
Toast.makeText(context, "Unable to add student. Please make sure the STUDENT ID is not in use and try again.", Toast.LENGTH_SHORT).show()
Log.e("realm", e.message.toString())
}
}
}
I tried realm.close()
then Realm.open(config)
in the catch block hoping it will solve the problem but to no avail. The error still pop up
I solved it by using try/catch
block inside the realm.writeBlocking
as shown below
fun addStudent(mID: String, mName: String, mSex: Char): Boolean {
var success = false
realm.writeBlocking {
try {
this.copyToRealm(Student().apply {
_id = mID
name = mName
sex = mSex
})
Log.v("realm","$mName was added!")
success = true
}catch (e: IllegalArgumentException){
Log.e("realm", e.message.toString())
success = false
}
}
return success
}
And the onclickListener for the SAVE button as follows:
if (dbHelper.addStudent(id, name, sex)){
Toast.makeText(context,"$name was added!", Toast.LENGTH_SHORT).show()
studentID.setText("")
studentName.setText("")
studentName.requestFocus()
getStudents()
}else {
Toast.makeText(context, "The STUDENT ID you have entered is already in use."
, Toast.LENGTH_SHORT)
.show()
}
Thanks.