Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select few among all the nested entities : SPRING JPA

I have a scenario like below.

Lets say EntityA has three nested entities EntityB, EntityC, EntityD. And all of EntityB, EntityC, EntityD has several nested entities inside them.

But while selecting for EntityA it selects the whole tree of nested entities. Whereas I want to fetch a specific branch. Lets say only EntityA, EntityB and all sub entities of EntityB are to be fetched leaving EntityC and EntityD back then I am not sure how to do that. As spring jpa brings all the nested objects back to me.

I am using below collection mapping.


 @Entity
 @Table(name = "customer_party_mapping")
 @Data
 public class CustomerPartyMappingEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;
    
    @Column(name = "customer_id")
    private Integer custmerId;
    
    @Column(name = "orgtype_id")
    private Integer orgTypeId;
    
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn(name = "customer_party_mapping_id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<CustomerPartyBookingLocationEntity> customerPartyBookingLocation=new ArrayList<CustomerPartyBookingLocationEntity>();
    
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn(name = "customer_party_mapping_id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<CustomerPartyFieldMappingEntity> customerPartyFieldMappingEntity=new ArrayList<CustomerPartyFieldMappingEntity>();

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn(name = "customer_party_mapping_id",referencedColumnName="id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<CustomerPartyOtherDocumentEntity> otherDocumentsList=new 
    ArrayList<>();
    
    @OneToOne( cascade={ CascadeType.PERSIST, CascadeType.MERGE })
    @JoinColumn(name = "customer_name_screening_id", referencedColumnName="id") 
    private CustomerNameScreeningEntity customerNameScreeningEntity;
        
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn(name = "customer_party_mapping_id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<CustomerDocInfoTrackingEntity> customerDocInfoTrackingList=new 
    ArrayList<CustomerDocInfoTrackingEntity>();
}

And I am calling


List<CustomerPartyMappingEntity> customerPartyMappingEntityList = customerPartyMappingRepository.findByCustmerId(customerid);

It gets all the nested mapped list of entities wheras I need only CustomerPartyMappingEntity and its list of customerPartyFieldMappingEntity nested object.

Any help will be appreciated.

like image 747
Sneh Avatar asked Aug 02 '20 06:08

Sneh


People also ask

What does findById return in JPA?

Its findById method retrieves an entity by its id. The return value is Optional<T> . Optional<T> is a container object which may or may not contain a non-null value. If a value is present, isPresent returns true and get returns the value.

What is @query annotation in spring boot?

The @Query annotation declares finder queries directly on repository methods. While similar @NamedQuery is used on domain classes, Spring Data JPA @Query annotation is used on Repository interface. This frees the domain classes from persistence specific information, which is a good thing.

What is @entity annotation in spring boot?

The @Entity annotation specifies that the class is an entity and is mapped to a database table. The @Table annotation specifies the name of the database table to be used for mapping.

What is @ManyToOne annotation in spring boot?

The @ManyToOne annotation is used to define a many-to-one relationship between two entities in Spring Data JPA. The child entity, that has the join column, is called the owner of the relationship defined using the @ManyToOne annotation.


1 Answers

First use FetchType.LAZY for nested entity. Then you can use @EntityGraph to fetch nested entity by name and their nested entity using their name with . in the repository. You use to just specify the nested property in attributePaths like

@EntityGraph(attributePaths = {"customerPartyBookingLocation"})

And the nested property of customerPartyBookingLocation like

@EntityGraph(attributePaths = {"customerPartyFieldMappingEntity.subField"})

Example:

@EntityGraph(attributePaths = {"customerPartyBookingLocation", "customerPartyFieldMappingEntity.subField"})
List<CustomerPartyMappingEntity> findByCustmerId(Integer customerid);

Note: You can't use @EntityGraph with @Query annotation

like image 83
Eklavya Avatar answered Oct 13 '22 00:10

Eklavya