在Spring数据仓库接口中实现常规接口

问题描述 投票:0回答:2

我正在使用一个扩展 Spring Data JpaRepository 的存储库,并希望让它扩展另一个接口。

以前,我的数据库存储库看起来像这样:

interface PublicTransportPricingZoneRepository : JpaRepository<PublicTransportPricingZone, Long> {

}

我现在创建了另一个界面

TransitTicketRepo
,定义如下

interface TransitTicketRepo {
    fun findPossibleTickets(geometry: Geometry): Collection<TransitTicket>
}

现在想使用

PublicTransportPricingZoneRepository
中的默认方法实现接口。我尝试通过将 PublicTransportPricingZoneRepository 的代码更改为

来解决此问题
interface PublicTransportPricingZoneRepository : JpaRepository<PublicTransportPricingZone, Long>, TransitTicketRepo {
    fun findPossibleTickets(geometry: Geometry): Collection<TransitTicket> {
       // do something
       return emptyList()
    } 
}

但启动应用程序时收到以下错误消息。

org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.Collection PublicTransportPricingZoneRepository.findPossibleTickets(Geometry); Reason: Failed to create query for method public abstract java.util.Collection...

我假设解决方案是以某种方式告诉 spring data 停止自动生成

findPossibleTickets
的查询,但一直无法找出如何实现。

kotlin spring-data-jpa spring-data
2个回答
0
投票

我最近再次遇到了这个问题(请参阅前面的评论),其中 Spring Boot Data 尝试生成接口的实现,尽管已经有一个实现。这与原来的问题并不完全相同,但也许我的解决方案对某人有用。

我从这个开始:

data class MyEntity(val name: String, val creationDateTime: ZoneDateTime)

@Repository
interface MyEntityRepository : JpaRepository<MyEntity, Long> {
  fun findFirstByNameOrderByCreationDateTimeDesc(name: String)
}

函数

findFirstByNameOrderByCreationDateTimeDesc
有一个非常长且令人困惑的名称,所以我只是想添加一个默认函数
findMostRecent
来指向另一个函数。

我最初的尝试是这样的:

data class MyEntity(val name: String, val creationDateTime: ZoneDateTime)

@Repository
interface MyEntityRepository : JpaRepository<MyEntity, Long> {
  fun findFirstByNameOrderByCreationDateTimeDesc(name: String)
  fun findMostRecent(name: String) = findFirstByNameOrderByCreationDateTimeDesc(name)
}

但是,这以

PropertyReferenceException
结束,因为 Spring Boot Data 会尝试在
MyEntity
上创建属性“findMostRecent”的实现,而这显然不存在。

在网上,您可以找到涉及添加另一个接口并具有抽象类实现的解决方案,但这些对我不起作用,因为我想引用接口中获取生成的实现的函数。

最终我决定使用 Kotlin 扩展函数 将所需的函数添加到存储库中:

data class MyEntity(val name: String, val creationDateTime: ZoneDateTime)

@Repository
interface MyEntityRepository : JpaRepository<MyEntity, Long> {
  fun findFirstByNameOrderByCreationDateTimeDesc(name: String)
}

fun MyEntityRepository.findMostRecent(name: String) = 
  findFirstByNameOrderByCreationDateTimeDesc(name)

通过这个我可以在存储库上调用

myEntityRepository.findMostRecent("someValue")
,而不会出现 Spring Boot Data 投诉。


-1
投票

你可以这样做这样

简而言之:

@Repository
// Your bean that will be glued together by spring
interface PublicTransportPricingZoneRepository extends JpaRepository<...>, PublicTransportPricingZoneCustomRepository {
  // Other methods, but everything must be annotated with @Query or possible for spring to guess what it needs to do from its name (google derived methods)
}

interface PublicTransportPricingZoneCustomRepository {
  // define custom methods
  List<String> nameIsNotImportant();
}

@Service
// naming here is important - it must be names as interface + Impl, otherwise spring won't pick it up
// apart from that, it's a regular bean - you can Autowire, etc
class PublicTransportPricingZoneCustomRepositoryImpl implementats PublicTransportPricingZoneCustomRepository {
  // Implement custom methods
  @Overridden
  public List<String> nameIsNotImportant() {
    // impl
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.