M.Haris Qayyum
M.Haris Qayyum

Reputation: 137

Springboot JPA entity is auto loading lazy join entities

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.

Upvotes: 2

Views: 1121

Answers (3)

M.Haris Qayyum
M.Haris Qayyum

Reputation: 137

Thanks to everyone for providing workarounds... But every work item requires lots of changes which were not possible for me...

Luckily I found a solution that is working fine for me... Better to post here...

Step-1: Add dependency in pom.xml file

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-hibernate5</artifactId>
</dependency>

Step-2: Add a 'Bean' for Hibernate Module

We can add bean in any file having @Configuration annotation... Even, we can add in Springboot main application file(where we have main method).

@Bean
public Module datatypeHibernateModule() {
    return new Hibernate5Module();
}

That's it, Happy Coding...

Upvotes: 0

serob
serob

Reputation: 26

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

Upvotes: 0

Jo&#227;o Dias
Jo&#227;o Dias

Reputation: 17510

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).

Upvotes: 1

Related Questions