Home > Back-end >  How to ignore attributes from being SELECTed in JPA NamedEntityGraph?
How to ignore attributes from being SELECTed in JPA NamedEntityGraph?

Time:09-30

I'm creating a couple of NamedEntityGraphs in my Entity. I have been able to stop JPA from joining other tables by not including the attribute in the NamedAttributeNode.

But for the rest of attributes like dates, strings, etc they will always appear in the query generated by Hibernate.

How can I prevent hibernate from selecting those columns?

Please don't tell me to ignore it in the view layer, the point of not fetching the rest of the columns is for optimization of the query/network.

Also I know I can use @Query in my spring repository but I want to keep my repositories clean.

And the same goes for not creating new entity classes with fewer attributes, I want to reuse the entities.

CodePudding user response:

You said:

Also I know I can use @Query in my spring repository but I want to keep my repositories clean.

The most common way of not selecting certain attributes is to use a native SQL query which only selects the columns you want, e.g.

@Query(value = "SELECT col1, col2 FROM some_table", nativeQuery = true)
List<Object[]> findOnlyTwoColumnsFromTable();

Instead of using List<Object[]>, you might also be able to define a DTO class which just has two fields in it, e.g. List<TwoColumnDTO>.

This may look messy, and certainly it is less clean than neatly using pure JPA to select into an entity class. But the thing to remember here is that the JPA methods are, at the end of the day, merely convenience methods. If they serve your purpose well, then use them. Otherwise, for most of your applications you will typically end up with a few native queries here and there, and there is nothing wrong it.

CodePudding user response:

You will need DTOs for this and I think this is a perfect use case for Blaze-Persistence Entity Views.

I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model.

A possible DTO model could look like the following with Blaze-Persistence Entity-Views:

@EntityView(User.class)
public interface UserDto {
    @IdMapping
    Long getId();
    String getName();
    Set<RoleDto> getRoles();

    @EntityView(Role.class)
    interface RoleDto {
        @IdMapping
        Long getId();
        String getName();
    }
}

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.

UserDto a = entityViewManager.find(entityManager, UserDto.class, id);

The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

Page<UserDto> findAll(Pageable pageable);

The best part is, it will only fetch the state that is actually necessary!

  • Related