1



I'm wondering if there is a way in which we can control lazy vs eager loading using rest service method calls. Let me elaborate.

I have an entity like below. I don't need the lazily loaded jobDocuments some times, but I need it some other times. Can I write 2 rest methods, one will return Job object with jobDocuments and the other one doesn't ?

@Table(name = "JOB")
public class Job implements Serializable {

  @Id
  @Column(name = "JOB_ID", unique = true, nullable = false)
  private Long id;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "job")
  @Column(name = "PRINT_JOB_ID", length = 30)
  private JobDocument jobDocuments;

}

1 Answer 1

4

I suggest you to not mix data model and representation (entity and http response in your case).

You can keep your Job entity with lazy loading by default, but don't use it as a rest service response. Create separate class which will represent http response and wrap data from your entity. For example:

@Table(name = "JOB")
public class Job implements Serializable {
    @Id
    @Column(name = "JOB_ID", unique = true, nullable = false)
    private Long id;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "job")
    @Column(name = "PRINT_JOB_ID", length = 30)
    private JobDocument jobDocuments;
    . . .
}

// your response class, which wrap Job data
public class JobResponse {
    @JsonProperty("id")
    private Long id;
    @JsonProperty("jobDocuments")
    private JobDocument jobDocuments
    . . .
    // use this when you need to have jobDocuments 
    public static JobResponse fromJobWithDocuments(Job job) {
        this.id = job.getId();
        this.jobDocuments = job.getJobDocuments(); // you fetch lazy field, so it would be pre-populated
    }

    // use this when you don't need to have jobDocuments 
    public static JobResponse fromJob(Job job) {
        this.id = job.getId();
    }
}

And suppose you have controller like that:

public class Controller {
    . . .
    public ResponseEntity<JobResponse> getJob(boolean withDocuments, long jobId) {
        JobResponse response;
        Job job = jobService.getJob(jobId); // assuming you are getting job somehow
        if (withDocuments) {
            response = JobResponse.fromJobWithDocuments(job)
        } else {
            response = JobResponse.fromJob(job)
        }
        return new ResponseEntity<JobResponse>(response);
    }
    . . .
}
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent answer! I checked the console logs and this prevents additional queries as set by lazy initialization. If model object is used jackson serializer would invoke getters and then the child entities are fetched anyways. So the whole purpose of setting lazy true is in vain!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.