Coming from Java where nullability is sort of a fr...
# getting-started
p
Coming from Java where nullability is sort of a free for all, I wonder how do you resolve this problem. I have a
User
data class which has a
type
field. The type can be either
REGULAR
or
ADMIN
. When it is of type
ADMIN
the user will always have a not null
companyId
but when it is a
REGULAR
user the
companyId
will always be null. Therefore the
companyId
now has to be nullable and I am forced to handle it even in this case:
Copy code
val user = db.getUser(id)
if (user.type == ADMIN) {
  // user.companyId is definitely NOT NULL here but the compiler obviously has no idea
} else {
  // user is a REGULAR user so the companyId is null
The only way around this is to have two different classes: an
AdminUser
and
RegularUser
that will reflect the reality more closely. Is there a better way? In Java the compiler does not care and I get no warnings.
h
Different classes is probably the best way. Having flags that determine the presence of other fields is a code smell.
6
p
Having a user type is a code smell?
All the users are stored in the same database table. It is very common to map one table to one Java POJO.
r
Instead of having "type" field consider having different implementations of user. Thats what Henning Hoefer states i guess.
s
You have to encode it in the types somehow. If your objection to
AdminUser
and
RegularUser
is duplication then maybe you should just have a
val User.adminData: AdminData?
that exposes these non null values
p
I am just wondering how would you do it because it seems like a very common use case. Would you really map one db table to two different classes?
t
Could you have your “type” be a sealed class hierarchy where the
Admin
type has a non-null companyId.
The compiler will give you the guarantees you want then
h
@poohbar It is pretty common. In JPA it's called "Table per class hierarchy": https://www.baeldung.com/hibernate-inheritance#single-table
1
p
I see.. yeah this is what I am doing. Most of my tables have a
type
column which determines their place in the "hierarchy". Except I didn't really model the hierarchy in my data classes.
I guess I could completely hide the
type
from kotlin and only the function that maps the db row to data class would know about it and create the correct subtype of
User
👍 2
a
How is your data mapped in the Database? A
User
-Table and another table
Admin
with a foreign key to
User
plus the
companyId
?
p
no.. there is just one table called
user
it has a column
type
and nullable column
companyId
the
companyId
is only null when
type
is not
ADMIN
n
if you’re using hibernate there’s a mapping strategy for that https://www.baeldung.com/hibernate-inheritance #3 One table per class hierarchy
p
jOOQ forever!
n
then you’re on your own...