Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring data JPA for returning specific fields

Does Spring Data have a mechanism for returning specific fields?

I'm familiar with the syntax:

Invoice findByCode(String code);

How about this:

Integer findIdByCode(String code);

which returns the id field only. Or

Tuple findIdAndNameByCode(String code);

which returns a tuple. Or

Invoice findIdAndNameByCode(String code);

which returns an entity only populated with specific fields. Can use a constructor taking only those field if defined - else construct empty and populate the fields.

EDIT

To qualify some more, I'm aware of solutions like @Query, constructor expressions and now, @NamedEntityGraph. My question is simply - does Spring data support such a shorthand syntax as I'm suggesting?

If not, perhaps this is a cool enhancement for a later version...

I'm not looking for workarounds.

like image 554
Gilbert Avatar asked May 22 '15 12:05

Gilbert


2 Answers

You can use JPQL Constructor Expressions:

SELECT NEW com.company.PublisherInfo(pub.id, pub.revenue, mag.price)
    FROM Publisher pub JOIN pub.magazines mag WHERE mag.price > 5.00

The constructor name must be fully qualified

like image 76
Robert Niestroj Avatar answered Sep 19 '22 12:09

Robert Niestroj


Not sure if what you're trying to achieve is the same as using multiple projections on the same JPA generated query (where method name are the same). I have posted an answer in this post.

https://stackoverflow.com/a/43373337/4540216

So I've managed to figure out how to use multiple projections with a single query.

<T> T getByUsername(String username, Class<T> projection) This allows the method caller to specified the type of projection to be

applied to the query.

To further improve this so it is less prone to error, I made a blank interface that the projection will have to extend in order to be able to insert class into the parameter.

public interface JPAProjection {
}

public interface UserRepository extends CrudRepository<UserAccount, Long> {
    <T extends JPAProjection > T getByUsername(String username, Class<? extends JPAProjection> projection);
}

Projection Interface

public interface UserDetailsProjection extends JPAProjection{
    @Value("#{target.username}")
    String getUsername();

    @Value("#{target.firstname}")
    String getFirstname();

    @Value("#{target.lastname}")
    String getLastname();
}

Then I can call the query method by

getByUsername("...", UserDetailsProjection.class)
like image 23
XPLOT1ON Avatar answered Sep 21 '22 12:09

XPLOT1ON