I have a "Test" class, with a "Questions" property which at the same time has an "Images" property, and I've also three DTO classes, "TestDTO", "QuestionDTO" and "ImageDTO" (both "Questions" and "Images" are Lists).
I can map Test to TestDTO almost without problems with ModelMapper, the resultant TestDTO has the List QuestionDTO with data, but even though each QuestionDTO in the List contains a List ImageDTO, the List contains empty ImageDTO objects.
Test:
@DynamoDBTable(tableName = AWSTables.Tables.TESTS)
class Test(@get:DynamoDBHashKey(attributeName = TableTest.test_id) var idTest: String = "",
@get:DynamoDBAttribute(attributeName = TableTest.test_type) var idTestType: String = "",
@get:DynamoDBAttribute(attributeName = TableTest.test_subject) var idTestSubject: String = "",
@get:DynamoDBAttribute(attributeName = TableTest.test_lng) var testLng: String = "",
@get:DynamoDBAttribute(attributeName = TableTest.test) var testName: String = "",
@get:DynamoDBAttribute(attributeName = TableTest.test_level) var testLevel: Int = 0,
@get:DynamoDBAttribute(attributeName = TableTest.test_level_number) var testLevelNumber: Int = 0,
@get:DynamoDBAttribute(attributeName = TableTest.time_limit) var timeLimit: Int = 0,
@get:DynamoDBAttribute(attributeName = TableTest.permitted_errors) var permittedErrors: Int = 0,
@get:DynamoDBAttribute(attributeName = TableTest.timestamp) var timestamp: Int = 0,
@get:DynamoDBAttribute(attributeName = TableTest.f_p) var fp: String = ""
):Serializable {
@get:DynamoDBAttribute(attributeName = AWSTables.TableTest.active)
var active: String = ""
var score = 0
var questions: MutableList<Question> = mutableListOf()
override fun toString(): String {
return testName
}
}
TestDTO:
class TestDTO : Serializable {
var idTest: String = ""
var idTestType: String = ""
var idTestSubject: String = ""
var testLng: String = ""
var testName: String = ""
var testLevel = 0
var testLevelNumber = 0
var timeLimit = 0
var permittedErrors = 0
var timestamp = 0
var questions: MutableList<QuestionDTO> = mutableListOf()
var answeredQuestions: List<AnswerDTO> = listOf()
var active: String = ""
var fp: String = ""
var score = 0
var recordTag: String = ""
var chartTag: String = ""
var testState4Records: String = ""
var testScore4Records = 0
var testResult = 0
var testState: String = ""
var timerState = 0
var averageQuestionTime = 0
var timerPreference = 0
var correctAnswers = 0
var incorrectAnswers = 0
var notAnsweredQuestions = 0
var testScore = 0
var testTime: String = ""
constructor()
constructor(questions: MutableList<QuestionDTO>) {
this.questions = questions
}
override fun toString(): String {
return testName
}
}
QuestionDTO:
class QuestionDTO : Serializable {
var idQuestion: String = ""
var idTest: String = ""
var idCorrectAnswer: String = ""
var question: String = ""
var instructions: String = ""
var explanations: String = ""
var timestamp = 0
var questionNumber = 0
var urlAudio: String = ""
var images: MutableList<ImageDTO> = mutableListOf()
var answers: MutableList<AnswerDTO> = mutableListOf()
}
ImageDTO:
class ImageDTO : Serializable {
val idImage: String = ""
val idQuestion: String = ""
val image: String = ""
val timestamp: Int = 0
var saveMode: String = ""
}
Map method:
fun <T, D> mapAll(entityList: Collection<T>?, outCLass: Class<D>?): ArrayList<D>? {
if (entityList.isNullOrEmpty()) return null
val listType = TypeToken.getParameterized(
MutableList::class.java, outCLass
).type
return modelMapper!!.map(entityList, listType)
}
Where I map:
override fun getTests(strSearchConfig: String): List<TestDTO>? {
val active: String
val tmVersion: String
var filteredTests: List<Test>? = null
var resultOK = true
try {
//get search configuration
val objJSON = strSearchConfig.toJson()
active = objJSON!!.getString("active")
tmVersion = objJSON.getString("tmVersion")
//unmodifiable lists with results stored in a class object
val awsTables = readAllTables()
//first generate list of tests object
filteredTests = AWSHelper.getFilteredTests(active, tmVersion, awsTables)
} catch (e: Exception) {
resultOK = false
e.logException()
}
return if(resultOK) mapAll(filteredTests, TestDTO::class.java) else null
}
How can I investigate why this is happening?
Ok, I will answer myself. The problem was very subtle in order to see it at first sight. The properties in "ImageDTO" class were declared as val, instead of var, what means they are read only. Changed all declarations from val to var and now it's working correctly.
@JsonClass(generateAdapter = true)
class ImageDTO : Serializable {
var idImage: String = ""
var idQuestion: String = ""
var image: String = ""
var timestamp: Int = 0
var saveMode: String = ""
}