Skip to content

Add EntityInformationAware interface to get EntityInformation<T, ID> in custom repository #3996

@ars-java

Description

@ars-java

I wanna create MyBaseRepository<T,ID> having custom JPA methods but I wanna use it as base repository just for few repositories, not all because I don't wanna use @EnableJpaRepositories(repositoryBaseClass = ...) for it. But there's a problem when I try to implement generic methods in such custom repository.

interface MyEntityRepository: JpaRepository<MyEntity, MyId>, MyCustomJpaRepository<MyEntity, MyId>

@NoRepositoryBean
interface MyCustomJpaRepository<T, ID : Serializable> : JpaRepository<T, ID> {
    fun myMethod(id: ID): T?
}

class MyCustomJpaRepositoryImpl<T, ID : Serializable>(
    @Autowired private val entityManager: EntityManager,
) : MyCustomJpaRepository<T, ID> {

    override fun myMethod(id: ID): T? {
        val entity = entityManager.find(clazz, albumId) ?: return null // No Class<T> here and no way to get it in runtime
        entityManager.remove(entity)
        return entity as T
    }
}

We can add to Spring Data interface to solve this problem (analog of other Spring Aware interfaces):

interface EntityInformationAware<T, ID> {
    void setEntityInformation(entityInformation: EntityInformation<T, ID>);
}

and process its existence during repository instance creation.

Then everybody can use EntityInformation, not framework implementations.

class MyCustomJpaRepositoryImpl<T, ID : Serializable>(
    @Autowired private val entityManager: EntityManager,
) : MyCustomJpaRepository<T, ID>, EntityInformationAware<T, ID> {
    private lateinit val entityInformation: EntityInformation<T, ID>

    override fun setEntityInformation(entityInformation: EntityInformation<T, ID>) {
        this.entityInformation = entityInformation
    }

    override fun myMethod(id: ID): T? {
        val type = entityInformation.javaType as JpaEntityInformation<T, ID>
        val entity = entityManager.find(type, albumId) ?: return null // Now we know Class<T> of Entity
        entityManager.remove(entity)
        return entity as T
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: declinedA suggestion or change that we don't feel we should currently apply

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions