I am trying to build a DTO (data-transfer-object) classes in Kotlin to be called from a Java application. Given following code:
BaseDto.kt
package sandbox.KotlinDataObjects
import org.apache.commons.lang3.builder.ToStringBuilder
import java.sql.ResultSet
import java.sql.SQLException
/**
* Base DTO
* (JSON/XML serialization code removed for clarity)
*/
abstract class BaseDto(
var id: Long = 0
) {
@Throws(SQLException::class)
open protected fun fromResultSet(rs: ResultSet) {
this.id = rs.getLong("id")
}
/**
* Override toString and use StringBuilder
* Since DataObject may be one of many objects based on BaseDto
* we want to avoid doing this in every data class
* Derived class seems to generate a toString and this never gets
* called, this is the issue I believe
*/
override fun toString(): String {
return ToStringBuilder.reflectionToString(this)
}
}
DataObject.kt
package sandbox.KotlinDataObjects
import org.apache.commons.lang3.builder.ToStringBuilder
import java.sql.ResultSet
data class DataObject(
var name: String = ""
) : BaseDto() {
override fun fromResultSet(rs: ResultSet) {
super.fromResultSet(rs)
name = rs.getString("name")
}
}
Main.java
package sandbox.KotlinDataObjects;
import org.mockito.Mockito;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Main {
/**
* Mock ResultSet for testing with columns we are requesting
* @return ResultSet
* @throws SQLException
*/
private static ResultSet getMockedResultSet() throws SQLException {
ResultSet mockedRs = Mockito.mock(ResultSet.class);
Mockito.when(mockedRs.getLong("id")).thenReturn(12L);
Mockito.when(mockedRs.getString("name")).thenReturn("MyName");
return mockedRs;
}
public static void main(String[] args) {
try (ResultSet mockedRs = getMockedResultSet()) {
// Read DataObject from ResultSet (mocked to avoid DB connection)
DataObject dobj = new DataObject();
dobj.fromResultSet(mockedRs);
System.out.println("toString: dobj="+dobj);
System.out.println("getters: dobj.name="+dobj.getName()+" dobj.id="+dobj.getId());
} catch (SQLException e) {
e.printStackTrace();
}
}
}
This displays:
toString: dobj2=DataObject(name=MyName)
getters: dobj2.name=MyName dobj2.id=12
I would like to include the id field form the BaseDto in the DataObject.toString call. One option is to override the toString with ToStringBuilder.reflectionToString in DataObject.toSting, but it would have to be added to every object derived from BaseDto. Is there a way to declare a data object hierarchy that automatically includes members from base classes. This is doable in java by overriding toString() in the base and using the ToStringBuilder.reflectionToString, in Kotlin the base toString is not called since data object generates its own version of toString which does not call super.