DEV Community

Salad Lam
Salad Lam

Posted on

What is implementation class of org.springframework.data.jpa.repository.JpaRepository interface?

Notice

I wrote this article and was originally published on Qiita on 17 September 2019.


From my notice board example application (Spring Data JPA version). You may notice that only 2 interface is defined only on repository layer

interface.png

no implementation class on these interface is defined. So what actual instance is injected into info.saladlam.example.spring.noticeboard.service.MessageServiceImpl?

That instance is a proxy, with target class instance org.springframework.data.jpa.repository.support.SimpleJpaRepository and many advice/advisor/interceptor is attached. One important interceptor is org.springframework.data.repository.core.support.RepositoryFactorySupport.QueryExecutorMethodInterceptor.

Definition of info.saladlam.example.spring.noticeboard.repository.MessageRepository

public interface MessageRepository extends JpaRepository<Message, Long> {

    @Query("SELECT m FROM Message m WHERE m.approvedBy IS NOT NULL AND m.publishDate <= :at AND (m.removeDate IS NULL OR m.removeDate > :at) ORDER BY m.publishDate DESC")
    List<Message> findPublished(@Param("at") LocalDateTime at);

    @Query("SELECT m FROM Message m WHERE m.approvedBy IS NULL ORDER BY m.publishDate DESC")
    List<Message> findWaitingApprove();

    @Query("SELECT m FROM Message m WHERE m.owner = :owner ORDER BY m.publishDate DESC")
    List<Message> findByOwner(@Param("owner") String owner);

}
Enter fullscreen mode Exit fullscreen mode

and its parent interface org.springframework.data.jpa.repository.JpaRepository

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

    List<T> findAll();
    List<T> findAll(Sort sort);
    List<T> findAllById(Iterable<ID> ids);
    <S extends T> List<S> saveAll(Iterable<S> entities);
    void flush();
    <S extends T> S saveAndFlush(S entity);
    void deleteInBatch(Iterable<T> entities);
    void deleteAllInBatch();
    T getOne(ID id);

    @Override
    <S extends T> List<S> findAll(Example<S> example);

    @Override
    <S extends T> List<S> findAll(Example<S> example, Sort sort);

}
Enter fullscreen mode Exit fullscreen mode

For example, when a method findAll() defined in JpaRepository is called, as result method findAll() of SimpleJpaRepository is called. And when a method findWaitingApprove() defined in MessageRepository is called, interceptor org.springframework.data.repository.core.support.RepositoryFactorySupport.QueryExecutorMethodInterceptor is involved. In method org.springframework.data.repository.core.support.RepositoryFactorySupport.QueryExecutorMethodInterceptor.doInvoke()

        @Nullable
        private Object doInvoke(MethodInvocation invocation) throws Throwable {

            Method method = invocation.getMethod();
            Object[] arguments = invocation.getArguments();

            if (hasQueryFor(method)) {
                return queries.get(method).execute(arguments);
            }

            return invocation.proceed();
        }
Enter fullscreen mode Exit fullscreen mode

queries is a map, which store org.springframework.data.jpa.repository.query.JpaQueryMethod instance with key method defined in MessageRepository.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)