Home > Software engineering >  Springboot JPA entity is auto loading lazy join entities
Springboot JPA entity is auto loading lazy join entities

Time:09-28

I have an entity as

    @Getter
    @Setter
    @Entity
    @Table(name = "feature")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    public class Feature {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;

        @Column(name = "name")
        private String name;

        @Column(name = "description")
        private String description;

        @OneToMany(mappedBy = "featureId", fetch = FetchType.LAZY)
        private transient Collection<FeatureComponent> components;
}

While in its Repository(Dao) file, I have

public interface FeatureDao extends JpaRepository<Feature, Integer> {

    @Query("SELECT e FROM Feature e")
    public List<Feature> getAll();

    @Query("SELECT e FROM Feature e LEFT JOIN e.components fc WHERE e.id= :id")
    public Feature getWithDetail(@Param("id") Integer id);
}

When I'm calling featureDao.getAll(); it returns all features but including components list filled and because of that, my response it being too large to load on client-side.

I'm unable to understand why it is happening when I'm using Lazy fetch mode and didn't mentioned joining with components in my getAll method.

Please help to resolve that issue, Thanks in advance.

CodePudding user response:

Just like @spOOm already mentioned I also suspect this is the side effect of Jackson Feature entity serialization into JSON triggering the load of all the components.

That is why using DTOs instead of plain Entities is usually advisable when returning data via a Controller. With DTOs, you clearly define whatever you want to include in the response to the caller. You can even reorganize your model so that it fits better the needs of the clients. You decouple your inner model and the model your API consumers know, making it possible to rework your inner model and still keep the same public model. You could have the following DTO.

public class FeatureSimpleDto {
    private Integer id;
    private String name;
    private String description;
}

Then, in your Controller or Service (here you can find different opinions) you would basically convert your Feature entity into a FeatureSimpleDto that would be returned by your Controller. Here you can use mapping libraries such as MapStruct or you can do it on your own (I usually tend to prefer doing it on my own, one less dependency to rely on).

CodePudding user response:

Using Lombok may be a problem, depending on the relationship between tables, try to create getters manually in entity classes.

  • Related