@NamedQuery override findAll in Spring Data Rest JpaRepository

22,903

Solution 1

Yes, you can create your Implementation of your Repository interface, there is acouple section in

http://docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/html/repositories.html#repositories.custom-implementations

Repository

   @Repository
    public interface PagLogRepository extends JpaRepository<PagLogEntity, Long>, PagLogCustomRepository {

Custom Interface

public interface PagLogCustomRepository {
PagLogEntity save(SalesForceForm salesForceForm) throws ResourceNotFoundException;

Custom implementation

public class PagLogRepositoryImpl implements PagLogCustomRepository {
@Override
    public PagLogEntity save(final SalesForceForm salesForceForm) throws ResourceNotFoundException {

        query = emEntityManager.createNamedQuery("findItemFileByDenormalizedSku", ItemFileEntity.class);
        query.setParameter("skuValue", rawSku);

Instead of override save make it with findAll, then you can create complex customization

Solution 2

In the upcoming version 1.5 (an RC is available in our milestone repositories) of Spring Data JPA you can simply redeclare the method in your repository interface and annotate it with @Query so that the execution as query method is triggered. This will then cause the named query to be looked up just as you're already used to from query methods:

interface UserJpaRepository extends PagingAndSortingRepository<User, Long> {

  @Query
  List<User> findAll();

  Page<User> findNameEqualsTest(Pageable pageable);
}

A few notes on your repository declaration:

  • You don't need to annotate the interface with @Repository. That annotation doesn't have any effect at all here.
  • Your @RestResource annotation configures the exporter in a way that will be the default anyway in Spring Data REST 2.0 (also in RC already). Ging forward, prefer @RestRepositoryResource, but as I said: the pluralization will be the default anyway.
  • We generally don't recommend to extend the store specific interfaces but rather use CrudRepository or PagingAndSortingRepository.
Share:
22,903
Ethan Anderson
Author by

Ethan Anderson

I'm a Software Engineer living and working in Minnesota. I enjoy designing systems and discovering elegant solutions to complex problems.

Updated on July 09, 2022

Comments

  • Ethan Anderson
    Ethan Anderson almost 2 years

    Is there a way to override the findAll query executed by Spring Data Rest?

    I need a way of filtering the results based on some specific criteria and it seems that using a @NamedQuery should be along the lines of what I'm looking for so I setup a test.

    @Entity
    @Table(name = "users")
    @NamedQueries({
        @NamedQuery(name = "User.findAll", query="SELECT u FROM User u WHERE u.username = 'test'"), 
        @NamedQuery(name = "User.findNameEqualsTest", query="SELECT u FROM User u WHERE u.username = 'test'")   
    })
    public class User implements Serializable, Identifiable<Long> { }
    

    With this in place I would expect SDR to utilize my findAll() query (returning 1 result) but instead it executes the same old findAll logic (returning all results).

    In my Repository I added:

    @Repository
    @RestResource(path = "users", rel = "users")
    public interface UserJpaRepository extends JpaRepository<User, Long> {
    
        public Page<User> findNameEqualsTest(Pageable pageable);
    }
    

    and in this case it DOES pick up the provided @NamedQuery. So...

    How should I go about overriding the default findAll() logic? I need to actually construct a complex set of criteria and apply it to the result set.

  • Ethan Anderson
    Ethan Anderson about 10 years
    Implemented and it's working. Was banging my head against the keyboard for a bit until I realized the importance of class names in this process.
  • Koitoer
    Koitoer about 10 years
    Indeed, it is a very common problem, asked several times in SOverflow, tutorial should include a note there
  • norgence
    norgence about 10 years
    As of Spring Data JPA 1.5 the custom implementation won't be necessary anymore to achieve this. See my answer for details.
  • Ethan Anderson
    Ethan Anderson about 10 years
    Much appreciated, Oliver! I watched your Repositories Deepdive talk last night and that really helped clear some things up for me. I'll be making some changes today to better implement your best practices.
  • Koitoer
    Koitoer about 10 years
    that is wont be necessary it does not means the answer is not correct, but sounds great new version stuff