"Nullsafety" of Kotlin Room "Single element" Query...
# room
r
"Nullsafety" of Kotlin Room "Single element" Query Given Room Dao Query:
Copy code
@Query("SELECT * FROM stations WHERE stationId = :stationId LIMIT 1")
    fun getStation(stationId: String): Station
What will happen if ":stationID" is not found, how is that element returned, null ? Above expression is set as "nullsafe" (No warning telling that I should return
Station?
instead,) and handle the null check in my code. AS should give a Lint Error/Warning here to tell that the result may return null. My app fails at this point when handling a null (that obviously shouldn't be null...) RG
I made an issuetracker on this, and we'll see if its catched: https://issuetracker.google.com/148596201
👍 1
k
Honestly I dont’ think it’s a linting issue. It’s an issue with the Room code that compiles an _Impl from the source interface. If the interface is written in Kotlin, the generated Java _Impl ought to do a null check and throw an exception. As it stands, it’s up to you to do it, sadly.
r
If there is an possibility of an API (as room is) returning null, Lint should flag that. I think this complies with the nullsafety of Kotlin.
k
How should that work? A dao’s
_impl
is autogenerated Java, and Java has no nullable marker, so your linter cannot possibly know that the Java function could return null.
Unfortunately, you have to outsmart the generator: any time your Kotlin DAO
interface
code SELECTs from the table, you should always put a
?
at the end of your return value if you’re querying a single value. Don’t do:
Copy code
@Query("SELECT * FROM foo LIMIT 1")
fun getFoo(): Foo
Do:
Copy code
@Query("SELECT * FROM foo LIMIT 1")
fun getFoo(): Foo?
or
Copy code
@Query("SELECT * FROM foo LIMIT 1")
fun getFoo(): LiveData<Foo>
(the latter bakes in a warning about nullability since
LiveData<A>.value: A?
by definition
r
Actually I agree with you here, but when inexperienced (and stressedout) programmers, there should just be a warning that the result may be null.
k
The thing is, I don’t know what the fix is. If you just had a Kotlin linter that warned about every nullable return value coming from Java, since Java doesn’t have a nullable marker (aside from an optional
@NotNull/@Nullable
annotation), your linter would probably highlight almost every Java function you call since most of them do not have those annotations (since they’re optional).
Room should have this prominently in its documentation about how to write a Dao interface
IMO Room should still be labeled beta, because this is a preetty big issue. Another big issue is:
Copy code
@Query("SELECT * FROM Foo")
fun getFoo(): Foo?
The query might select 50 rows, and it will pick 1 to return back. A query missing a LIMIT should error out on compile if your return value is not
List<A>
r
You coul add it as an option: Compile nullsafe -> This forces you to check for nulls on java libraries, Compile nullwarning ->You are wrned, Compile null silent -> You get no warning.
k
I suppose so. We’re now venturing beyond my knowledge, as I have never messed with the Kotlin linter and my compile options :)
r
Anyhow, kotlin is somehow ventured as a "nullsafe" language (opposite to java, c/c++ etc), so I think it would be acceptable to be more strict about it.