简体   繁体   中英

Spring JPA Projection findAll

Is it possible to use "findAll" for a JPARepository returning a Collection/List of Projections? Example:

@Entity
public class Login {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    private Integer id;

    private String name;

    private String pass;

    (...)

}

public interface LoginProjection {
    public String getName();
}

@Repository
public interface LoginRepository extends JpaRepository<Login, Long> {
    Login findByName(String name);

    @Query(value = "SELECT name FROM login", nativeQuery = true)
    List<LoginProjection> findAllLoginProjection();
}

Using @Query it works! But it is not possible to use

 List<LoginProjection> findAll();

Because LoginProjection it does not extends T (Login).

I was thinking if it is possible to give a "alias" for findAll like findAllXYZ that does the same thing as findAll. Using filters it works too, but I do not want to use them:

 List<LoginProjection> findAllByName(String name);

My main goal would be something like this:

@Repository
public interface LoginRepository extends JpaRepository<Login, Long> {
    Login findByName(String name);

    List<Login> findAll();

    List<LoginProjection> findAllLoginProjection();
}

Which is pretty easy and with "zero @Query"

And add a method to the repository:

List<LoginProjection> findAllProjectedBy();

The method name can be simplified to findBy() to match the documentation example at https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

I assume you're not using Spring Data REST , so @Projection won't help here. @pavel-molchanov showed one form of expressing the projection, another form is:

List<LoginProjection> findBy();

If you have more than one projection, you can avoid creating a method in the repository for each projection by using dynamic projections like eg this:

<T> List<T> findBy(Class<T> projection);

// usage e.g.
... = findBy(LoginProjection.class);
... = findBy(UserSummaryProjection.class);

if you want to be more flexible you can add to the repository this method

<T> List<T> findBy(Class<T> projection);

and then you can call it with the following

List<LoginProjection> rows = loginRepository.findBy(LoginProjection.class);

The advantage of this approach is that you can use all the projections you want using the same query

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM