mp9*_*1de 4 java spring-data kotlin
请考虑以下存储库接口声明:
interface KotlinUserRepository : Repository<User, String> {
fun findById(username: String): User
fun search(username: String) = findById(username)
}
Run Code Online (Sandbox Code Playgroud)
我正在声明一个默认search(…)调用的默认接口方法findById(…).
启动我的应用程序失败:
org.springframework.data.mapping.PropertyReferenceException: No property Search found for type User!
如何在Spring Data存储库接口中使用Kotlin默认方法并阻止PropertyReferenceException?
小智 8
正如 Ben 指出的那样,您现在可以(Kotlin 1.2.40+)使用@JvmDefault.
interface BatchRepository : PagingAndSortingRepository<Batch, Long> {
fun getAllByOrderByPriorityAscNameAsc(): List<Batch>
@JvmDefault
fun getForAdmin() = getAllByOrderByPriorityAscNameAsc()
}
Run Code Online (Sandbox Code Playgroud)
您需要使用以下内容在 build.gradle 中启用该选项:
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
freeCompilerArgs = ['-Xenable-jvm-default']
}
}
Run Code Online (Sandbox Code Playgroud)
我刚刚在 Kotlin 1.2.41 上对其进行了测试,并且可以正常工作。
Kotlin 1.1/1.2首先编译了抽象接口方法的默认方法.在Spring Data存储库接口中使用Kotlin的默认方法是不可能的.
Kotlin允许使用Java运行时版本1.6的默认接口方法.Java 1.8引入了JVM级缺省接口方法.这导致Kotlin使用不同的方法来编译默认接口方法而不是Java.
代码KotlinUserRepository编译为:
interface KotlinUserRepository extends Repository {
User findById(String username);
User search(String username);
@Metadata(…)
public static final class DefaultImpls {
public static User search(KotlinUserRepository $this, String username) {
Intrinsics.checkParameterIsNotNull(username, "username");
return $this.findById(username);
}
}
}
Run Code Online (Sandbox Code Playgroud)
该方法search(…)编译为抽象接口方法.实现位编译为DefaultImpls反映默认方法签名的类.KotlinUserRepository需要实现的类需要实现search(…).在纯Kotlin环境中使用接口将让Kotlin编译器创建实现位.
Spring Data存储库可以使用下面的代理.存储库中的每个方法都必须是:
在这种情况下,search(…)根据您实现Java接口的方式,任何自定义代码都不会实现.Spring Data尝试派生查询并将其视为域类的search(…)属性User.查找失败并抛出PropertyReferenceException.
这是一个已知的限制.
FWIW Kotlin 扩展方法在这里对我来说效果很好,1 个 .kt 文件:
interface FooRepository : JpaRepository<FooDb, UUID>
object FooRepositoryExtensions {
fun FooRepository.doFoo(something: String): FooDb {
// do whatever you want here, the 'FooRepository' instance is available via `this`
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1637 次 |
| 最近记录: |