Spring 为SimpleParepository查找方法指定查询提示 目标 我正在实现一个定制的基本存储库,目标是能够通过方法参数而不是方法注释指定实体图的属性节点。因此,我们不需要像 @EntityGraph(attributePaths = ["enrollments"]) fun findByIdFetchingEnrollments(id: Long): Optional<Student>

Spring 为SimpleParepository查找方法指定查询提示 目标 我正在实现一个定制的基本存储库,目标是能够通过方法参数而不是方法注释指定实体图的属性节点。因此,我们不需要像 @EntityGraph(attributePaths = ["enrollments"]) fun findByIdFetchingEnrollments(id: Long): Optional<Student>,spring,kotlin,spring-data-jpa,Spring,Kotlin,Spring Data Jpa,其中,默认情况下,“注册”、“收藏夹主题”和“收藏夹教师”是惰性获取实体字段,但有时需要急切地获取(以避免懒散初始化异常) 我所拥有的 这些是我的课程: // Base repository interface. All my repositories will extend this interface @NoRepositoryBean interface Repository<T, ID> : JpaRepository<T, ID> { fun fin

其中,默认情况下,
“注册”
“收藏夹主题”
“收藏夹教师”
是惰性获取实体字段,但有时需要急切地获取(以避免
懒散初始化异常

我所拥有的 这些是我的课程:
// Base repository interface. All my repositories will extend this interface

@NoRepositoryBean
interface Repository<T, ID> : JpaRepository<T, ID> {

    fun findById(id: ID, vararg attributeNodes: String): Optional<T>
    
    // other find methods

}
问题 问题在于,我没有看到一种简单的方法将javax.persistence.loadgraph提示添加到SimpleParepository传递给EntityManager.find的查询提示中。

我认为解决这一问题的最佳方法是重写SimpleParepository方法,该方法由
SimpleParepository
中的所有find方法使用。然后,我在
RepositoryImpl
中的代码将变得更加简单(覆盖所有find方法,并为每个方法添加提示和调用super方法)。但我不能重写它,因为
QueryHints
类是包私有的

如果SimpleParepository属性是可变的,我还可以向它添加查询提示(这在
getQueryHints()
方法中被考虑),但是它的所有属性都是只读的,我认为有时候
元数据
是空的(对此不确定,但它被标记为
@Nullable

studentRepository.findById(1L, "enrollments") 
// or
studentRepository.findById(1L, "favouriteSubjects", "favouriteTeachers")
// and others...
// Base repository interface. All my repositories will extend this interface

@NoRepositoryBean
interface Repository<T, ID> : JpaRepository<T, ID> {

    fun findById(id: ID, vararg attributeNodes: String): Optional<T>
    
    // other find methods

}
// Custom base class. Inherits SimpleJpaRepository

class RepositoryImpl<T, ID>(
        val entityInformation: JpaEntityInformation<T, Any?>,
        val em: EntityManager
) : SimpleJpaRepository<T, ID>(entityInformation, em), Repository<T,ID> {

    // This is basically a copy-paste of SimpleJpaRepository findById method implementation... 
    override fun findById(id: ID, vararg attributeNodes: String): Optional<T> {
    
        Assert.notNull(id, "The given id must not be null!")

        /*
        Because 'repositoryMethodMetadata!!.queryHints' is read-only, I have to create a new Map,
        put all the queryHints entries in it and put the 'javax.persistence.loadgraph' hint.
         */

        val graph = em.createEntityGraph(entityInformation.javaType)
        graph.addAttributeNodes(*attributeNodes)

        val hints: MutableMap<String, Any?> = HashMap()
        hints.putAll(repositoryMethodMetadata!!.queryHints)

        hints["javax.persistence.loadgraph"] = graph

        if (repositoryMethodMetadata == null) {
            return Optional.ofNullable(em.find(domainClass, id, hints))
        }

        val type = repositoryMethodMetadata!!.lockModeType

        return Optional.ofNullable(
                if (type == null) em.find(domainClass, id, hints)
                else em.find(domainClass, id, type, hints)
        )
    }

    /* 
    In order to implement the other find methods the same kind of copy-paste implementations
    needs to be done, which shouldn't be necessary but I'm not seeing how.
    */

}
@Configuration
@EnableJpaRepositories(
        "com.domain.project.repository",
        repositoryBaseClass = RepositoryImpl::class)
class ApplicationConfiguration