Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data Rest adding excerpt projection switches off lazy fetching

I'm new to Spring Data Rest and trying to play around with its basic concepts. Everything works well so far, but few days ago I noticed that the application performance suddenly dropped after putting the projections into business.

These are my entities, repositories and the projection

@Entity
public class Item {

    @Id
    @GeneratedValue(strategy = TABLE)
    private long id;

    private String code;

    private String name;

    @ManyToOne(targetEntity=Category.class)
    @JoinColumn(name="category_id", referencedColumnName="id")
    private Category category;

    //getters & setters
}

@Entity
public class Category {

    @Id
    @GeneratedValue(strategy = TABLE)
    private long id;

    private String name;

    @OneToMany(mappedBy="category", targetEntity=Item.class, fetch=FetchType.LAZY)
    private Set<Item> items;

    //getters & setters
}

@RepositoryRestResource(excerptProjection=ItemExcerpt.class)
public interface ItemRepository extends CrudRepository<Item, Long>{

}

@RepositoryRestResource
public interface CategoryRepository extends CrudRepository<Category, Long>{

}

@Projection(name="excerpt", types=Item.class)
public interface ItemExcerpt {

    String getName();
}

So, all worked fine untill I added the excerpt projection to the ItemRepository @RepositoryRestResource(excerptProjection=ItemExcerpt.class)

Before doing this, when I hit http://localhost:9191/categories Hibernate output was as I expected it to be:

select
        category0_.id as id1_0_,
        category0_.name as name2_0_ 
    from
        category category0_

This is the output that I get after adding excerptProjection=ItemExcerpt.class

Hibernate: 
    select
        category0_.id as id1_0_,
        category0_.name as name2_0_ 
    from
        category category0_
Hibernate: 
    select
        items0_.category_id as category4_1_0_,
        items0_.id as id1_1_0_,
        items0_.id as id1_1_1_,
        items0_.category_id as category4_1_1_,
        items0_.code as code2_1_1_,
        items0_.name as name3_1_1_ 
    from
        item items0_ 
    where
        items0_.category_id=?

My conclusion is that the excerpt projection makes lazy fetching being ignored on @OneToMany relationship, which leads to a performance drop. Does anyone know a way to bypass this issue, or is this maybe an expected behaviour?

like image 677
Petar Avatar asked Apr 07 '17 22:04

Petar


1 Answers

It isn't exactly that excerpt projections make lazy fetching be ignored. More specifically, it is that an excerpt projection is telling spring data to include the excerpted data wherever a collection resource would be returned. From the reference docs Projections Excerpts, "An excerpt is a projection that is applied to a resource collection automatically.". The unfortunate side-effect of this is that spring-hateoas then ignores that property and instead puts in the hypermedia link to the resource instead. There is no combination of annotations that i have found that will correct this behavior for you while preserving the output. @JsonIgnore will not prevent the extra queries. @RestResource(exported = false) will prevent the queries, but will also prevent the hypermedia link.

like image 184
Jason Avatar answered Sep 19 '22 15:09

Jason