3

I am trying to use entity graph for triggering lazy collections to load but unfortunately entity graph also triggers all nested collections. I am using spring-data-jpa-entity-graph library for creating entity graphs at runtime.

@Entity
public class Brand implements Serializable {
    @OneToMany(mappedBy = "brand", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Set<Vehicle> vehicles;
}
@Entity
public class Vehicle implements Serializable {
    @ManyToOne
    @JoinColumn(name = "brand_id")
    private Brand brand;
    @OneToMany(mappedBy = "vehicle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Set<VehiclePart> parts;
}
@Entity
public class VehiclePart implements Serializable {
    @ManyToOne
    @JoinColumn(name = "vehicle_id")
    private Vehicle vehicle;
}

Spring service with JPA repository:

public interface BrandsRepository extends EntityGraphJpaRepository<Brand, Long> {

    Page<Brand> findAll(Pagable pagable, EntityGraph entityGraph);
}
@Service
public class BrandsService {

    public List<Brand> find() {
        return repository.findAll(PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "id")), EntityGraphUtils.fromAttributePaths("vehicles")).getContent();
    }

}

In this case service also return parts collection for each vehicle but I would like to fetch only list of brands with vehicles collection for each brand.

How can we trigger to load lazy collections just on the first level (only brand's vehicles -- without vehicle's parts)?

user3714967
  • 1,575
  • 3
  • 14
  • 29
  • *unfortunately entity graph also triggers all nested collections.* How does this manifets itself? Where do you see the eagerly fetched collection? – Alan Hay Jul 31 '19 at 07:21
  • Do you have any idea how to prevent this. Since I set what to trigger exactly I could also set any other level somehow. But if all nested collections will fetch too we need a way to prevent it. Is there any other solution to trigger lazy collections to load without nested collections too. – user3714967 Aug 01 '19 at 05:52
  • 1
    If you answer the questions I asked then maybe...Where do you see this eagerly fetched data? – Alan Hay Aug 01 '19 at 07:09
  • I see in logs that SQL are executed. They are executed before mapping entity to dto. Then all data is visible in json from API. It looks like [{vehicles: [{parts:[{},{},{}]}]},{vehicles: [{parts:[{},{},{}]}]}] – user3714967 Aug 01 '19 at 07:21

1 Answers1

1

I had the same problem. In my case: Spring and hibernate acted correctly, but I can see, that unused (lazy) fields are queried from sql.

When you use the fields, then they will be loaded over sql.
Iam using lombok and @EqualsAndHashCode.Exclude and @ToString.Exclude helps to prevent that.

In your case: Add a DTO-layer. Do not return the entities themself.
Or use @JsonIgnore annotation to ignore fields.

akop
  • 5,981
  • 6
  • 24
  • 51