Search code examples
javagenericsspring-data-jpaspring-data

How to retrieve actual type arguments of Spring Data repositories at runtime?


Suppose I have this Repository:

public interface ProductRepository extends JpaRepository<Product, Integer> {}

and I want to know at runtime that this repository persists Products, not Accounts or anything else. So far I only came up with this solution:

Class<?> persistedClass = ((ParameterizedType) repository.getClass() // some Spring proxy
    .getInterfaces()[0] // ProductRepository or the like
    .getGenericInterfaces()[0]) // JpaRepository
    .getActualTypeArguments()[0] // the first type argument

Let's ignore this clumsiness for a moment (isn't it par for the course with Java Reflection API?). What's worse, I had to remove the --release option which makes the solution a bit less portable (it's enabled by default in IntelliJ). There's something that makes java.base (it's where ParameterizedType is) and --release not compatible which prevents compilation (I don't understand it very well)

Is there a better way to retrieve that information at runtime?


Solution

  • You can simply call AbstractRepositoryMetadata.getMetadata(…) and call getDomainType() etc. on the result.

    If you're interested in the reverse lookup, i.e. finding a repository for a domain type, you can create a Repositories(…) instance from a ListableBeanFactory which would find look up all metadata for repository instances registered in that very BeanFactory.