Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@NamedQuery override findAll in Spring Data Rest JpaRepository

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.

like image 798
Ethan Anderson Avatar asked Feb 12 '14 16:02

Ethan Anderson


People also ask

Which is better CrudRepository or JpaRepository?

Crud Repository doesn't provide methods for implementing pagination and sorting. JpaRepository ties your repositories to the JPA persistence technology so it should be avoided. We should use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not.

What is difference between PagingAndSortingRepository and JpaRepository?

PagingAndSortingRepository provides methods to do pagination and sort records. JpaRepository provides JPA related methods such as flushing the persistence context and delete records in a batch.

What is difference between CrudRepository and JpaRepository interfaces in Spring data JPA?

Their main functions are: CrudRepository mainly provides CRUD functions. PagingAndSortingRepository provides methods to do pagination and sorting records. JpaRepository provides some JPA-related methods such as flushing the persistence context and deleting records in a batch.

What is the difference between Findby and findAll in JPA?

No, there is no difference between them, they will execute exactly the same query, the All part is ignored by Spring Data when deriving the query from the method name.


2 Answers

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.
like image 178
Oliver Drotbohm Avatar answered Oct 19 '22 18:10

Oliver Drotbohm


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

like image 5
Koitoer Avatar answered Oct 19 '22 19:10

Koitoer