如何在Spring Data仓库接口中使用Kotlin默认方法? [英] How can I use Kotlin default methods with Spring Data repository interfaces?

查看:94
本文介绍了如何在Spring Data仓库接口中使用Kotlin默认方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下存储库接口声明:

Consider the following repository interface declaration:

interface KotlinUserRepository : Repository<User, String> {

  fun findById(username: String): User

  fun search(username: String) = findById(username)
}

我要声明默认的接口方法search(…),默认为调用findById(…).

I'm declaring a default interface method search(…) that defaults to invoking findById(…).

启动我的应用程序失败,并显示以下信息:

Starting my application fails with:

org.springframework.data.mapping.PropertyReferenceException: No property Search found for type User!

如何在Spring Data仓库接口中使用Kotlin默认方法并防止PropertyReferenceException?

How can I use Kotlin default methods with Spring Data repository interfaces and prevent PropertyReferenceException?

推荐答案

TL; DR

Kotlin 1.1/1.2首先将默认方法编译为抽象接口方法.在Spring数据存储库界面中无法使用Kotlin的默认方法.

TL;DR

Kotlin 1.1/1.2 compiles default methods to abstract interface methods in the first place. It's not possible to use Kotlin's default methods in Spring Data repository interfaces.

Kotlin允许使用Java运行时版本1.6的默认接口方法. JVM级别的默认接口方法是Java 1.8引入的.这导致Kotlin与Java使用不同的方法来编译默认接口方法.

Kotlin allows default interface methods with a Java runtime version 1.6. JVM-level default interface methods were introduced with Java 1.8. This causes Kotlin to use a different approach to compile default interface methods than Java does.

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);
    }
  }
}

方法search(…)编译为抽象接口方法.实现位编译为反映默认方法签名的类DefaultImpls.想要实现KotlinUserRepository的类是必需的.在纯Kotlin环境中使用该接口将使Kotlin编译器创建实现位.

The method search(…) compiles to an abstract interface method. The implementation bit compiles to a class DefaultImpls which reflects the default method signature. A class wanting to implement KotlinUserRepository is required to implement search(…). Using the interface in a pure Kotlin environment will let the Kotlin compiler create the implementation bits.

Spring数据存储库在下面与代理一起工作.存储库中的每个方法都必须是:

Spring Data repositories work with proxies underneath. Every method on a repository must be either:

  1. 由商店专用的存储库实现.
  2. 由自定义实现实现.
  3. Java 8默认方法.
  4. 使用查询注释进行注释.
  5. 调整方法命名方案以允许查询派生.

在这种情况下,根据您实现Java接口的方式,任何自定义代码都不会实现search(…). Spring Data尝试派生查询,并将search(…)视为User域类的属性.查找失败并抛出PropertyReferenceException.

In this case, search(…) is not implemented by any custom code according to how you'd implement a Java interface. Spring Data attempts to derive a query and considers search(…) as property of the User domain class. Lookup fails and throws PropertyReferenceException.

这是一个已知的限制.

  • DATACMNS-1223 - Kotlin interface default methods are considered query methods.
  • KT-4779 - Generate default methods for implementations in interfaces.

这篇关于如何在Spring Data仓库接口中使用Kotlin默认方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆