Fetch List Using DTO projections using a Constructor Expression and JPQL

前端 未结 3 1174
無奈伤痛
無奈伤痛 2021-02-13 18:14

Perform a search on DisabScreenRequest and fetch its child details also. Using DTO projections using a Constructor Expression and JPQL.

The parent entity with a child

相关标签:
3条回答
  • 2021-02-13 18:50

    AFAIK, you can't use constructor expression which take a Collection.

    See the JPA 2.2 Spec, section 4.14 BNF, read about the constructor expression:

    constructor_expression ::=
        NEW constructor_name ( constructor_item {, constructor_item}* )
    constructor_item ::=
        single_valued_path_expression |
        scalar_expression |
        aggregate_expression |
        identification_variable
    
    0 讨论(0)
  • 2021-02-13 18:54

    If you need to fetch parent entity with a collection of its nested child entities you can use this simple approach using @EntityGraph annotation or JPQL with join fetch:

    @Entity
    public class Parent {
        //...
        @OneToMany
        private List<Child> children;
    }
    
    @Entity
    public class Child {
        //...
    }
    
    interface ParentRepo extends JpaRepository<Parent, Integer> {
    
        // with @EntityGraph
        @EntityGraph(attributePaths = "children")
        @Override
        List<Parent> findAll(); 
    
        // or manually
        @Query("select distinct p from Parent p left join fetch p.children")
        List<Parent> findWithQuery(); 
    }
    

    Note to use distinct in your query to avoid duplicate records.

    Example: duplicate-parent-entities

    More info: DATAJPA-1299

    0 讨论(0)
  • 2021-02-13 18:58

    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 defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure the way you like and map attributes(getters) via JPQL expressions to the entity model. Since the attribute name is used as default mapping, you mostly don't need explicit mappings as 80% of the use cases is to have DTOs that are a subset of the entity model.

    A mapping for your model could look as simple as the following

    @EntityView(DisabScreenRequest.class)
    interface RequestSearchDto extends Serializable {
      @IdMapping
      long getRequestId();
      Long getCivilId();
      Set<DisabMaster> getDisabilities();
    }
    

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

    RequestSearchDtodto = entityViewManager.find(entityManager, RequestSearchDto.class, id);

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

    0 讨论(0)
提交回复
热议问题