spring-data-redis icon indicating copy to clipboard operation
spring-data-redis copied to clipboard

Kotlin does not consider `@Nullable` annotation from `RedisOperations`

Open ghoonch4 opened this issue 4 years ago • 6 comments

There is a type issue in Kotlin due to the missing @Nullable annotation.

ghoonch4 avatar Dec 05 '21 10:12 ghoonch4

Nullability constraints are typically inherited for methods that specify e.g. @Nullable on the interface level.

https://github.com/spring-projects/spring-data-redis/blob/b67f1339b2b8ea29b3ca79fec467ffaffc57d918/src/main/java/org/springframework/data/redis/core/RedisOperations.java#L75-L76

Do you have further pointers regarding that issue towards how Kotlin considers nullability annotation rules?

Paging @sdeleuze

mp911de avatar Dec 09 '21 09:12 mp911de

@mp911de I tried it based on your comments. In Java, as you said, it inherits the @Nullable annotation specified on the interface level, but in Kotlin it is not.

Here's my situation: 스크린샷 2021-12-10 오전 1 18 55

ghoonch4 avatar Dec 09 '21 17:12 ghoonch4

Thanks a lot, that's quite interesting and likely a subject to happen in other places as well that use nullability annotations on interfaces.

mp911de avatar Dec 10 '21 08:12 mp911de

Seems that this is a general issue: https://github.com/spring-projects/spring-framework/issues/20424

mp911de avatar Dec 10 '21 08:12 mp911de

I understand that this is a general issue that can happen in other places as well.

For one more reason, for code consistency, I think it's better to add @Nullable annotation to RedisTemplate#execute(SessionCallback) method. The RedisTemplate#execute(RedisCallback) method, like the RedisTemplate#execute(SessionCallback) method, is annotated with @Nullable at the interface level, but is annotated with @Nullable once again. I think this difference can be confusing. I wonder what you think!

ghoonch4 avatar Dec 13 '21 13:12 ghoonch4

I wonder why Kotlin considers JSR-305 so much different than Java tooling does. Regardless, if a method is @Nullable on the interface level, then it is expected to adhere to that contract in the implementation method. The only exception is if the implementation method is annotated with @NonNull. The …Operations interfaces are designed to be the entry-point and to not use the concrete implementation directly unless necessary.

The annotation on <T> T execute(RedisCallback<T> action) is an oversight and comes from the initial introduction of nullability annotations. <T> T execute(RedisCallback<T> action, boolean exposeConnection) is annotated with @Nullable while it is not a method that is exposed on the interface.

mp911de avatar Dec 13 '21 13:12 mp911de