When using Kotlin in an Enterprise Environment ™, ...
# announcements
g
When using Kotlin in an Enterprise Environment ™, I make a model for MyBatis like so:
Copy code
class UserModel(
  val memberKey: Long? = null // val memberKey: Long doesn't work, because it won't create a noarg default constructor - MyBatis doesn't work without a default constructor. Therefore, we have to supply a default value to it.
)
However, memberKey being nullable creates headaches in the business logic because
!!
or
.?
has to follow around all the frickin time. Some people could recommend something like this:
Copy code
class UserModel(
  val memberKey: Long = 0L
)
But, this creates another pack of worms since omitting memberKey by accident in the business logic will result in inserting a user with literally 0L memberKey, which leads us to validating
!= 0
manually in
@Service
or wherever appropriate. What I would've done if Long wasn't a primitive is
Copy code
class UserModel{
  lateinit var memberKey: Long
}
But alas, Kotlin, due to its infinite wisdom, has decided against supporting
lateinit
in primitives. Any thoughts?
i
Does MyBatis support private constructors? If so, provide a secondary constructor that uses a default value of 0, and make that constructor private
Or, you could do the following:
Copy code
data class MyClass(
    private val _id: Long = 0,
    ..., 
    ...
) { 
  val id: Long get() { 
     return if(_id == 0) throw RuntimeException() else id 
  } 
}
j
It's not kotlin related, but I am under the Impression that mybatis does not require a default constructor with the
<constructor>
tag or
@Constructor
annotation. May be wrong
a
Maybe this would work in your case:
Copy code
class UserModel {
    var memberKey: Long by notNull()
}
d
Seems to be an architecture problem at first glance. The Problem shouldn't exist. You have your MyBatis entities and then you use a converter to convert it to a model you use in your business logic. This way you are free to worry about peculiarities of the persistence framework in your business code. For example I hava a
LevelRoomEntity
in my project which is the object saved by the room database and then I map/convert it to a
Level
which does not know anything about room
So for MyBatis you can create a class with only a default constructor and public
var
fields if need be. This would be fine since it would never be used in business code
g
Thanks for all the replies, I couldn't react promptly. As Daniel has pointed out, I do agree this is partly an architectural problem. To summarize, mybatis' peculiarity is forcing either a noarg constructor(have to provide default value to all fields) or a allarg constructor with everything neatly in order(not feasible in many cases) as far as I know. Separating entities with DTO does sound fair - it just hasn't been done in the codebase I'd been working on. Any workaround to this does seem quite hacky.