Avoiding unnecessary database calls when converting JPA Entity to DTO in Spring Boot with GraphQL

Avoiding unnecessary database calls when converting JPA Entity to DTO in Spring Boot with GraphQL


0

I am developing an application using Spring Boot and GraphQL. When returning an Entity directly from GraphQL, data fetchers automatically handle the queries, fetching only the tables requested in the GraphQL query.

For instance:

query Workspace {
    workspace {
        id
    }
}

This will only query the workspace table.

query Workspace {
    workspace {
        id
        users {
            id
        }
    }
}

This will query both the workspace and user tables.

However, when I return a DTO, because I explicitly call getUsers in my transformation logic, it fetches the users as well, leading to unnecessary database calls.

Here are my JPA Entities:

@Entity
public class Workspace {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @OneToMany(mappedBy = "workspace", fetch = FetchType.LAZY)
    private Set<User> users;
}

@Entity
public class User {
    private String fullName;
    @ManyToOne(fetch = FetchType.LAZY)
    private Workspace workspace;
}

This is my service layer method:

public WorkspacePayload getWorkspace() {    
    Workspace workspace = workspaceRepository.findById(1L)    
                       .orElseThrow(() -> new GraphQLException("Workspace not found"));    
    return WorkspaceUtil.prepareWorkspacePayload(workspace);
}

And the transformation logic:

public WorkspacePayload prepareWorkspacePayload(Workspace workspace) {
    return WorkspacePayload.builder()
        .id(workspace.getId())
        .name(workspace.getName())
        .users(getUsers(workspace))
        .build();
}

private List<UserPayload> getUsers(Workspace workspace) {
    return workspace.getUsers().stream()
        .map(workspaceUser -> UserPayload.builder()
                            .id(workspaceUser.getId())
                            .fullName(workspaceUser.getFullName())
                            .build())
        .collect(Collectors.toList());
}

My challenge: How can I optimize my service layer to ensure that I don’t make unnecessary database queries when I want to return DTOs instead of entities? What is the best practice for this scenario?

New contributor

Fatih Aksoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


Load 7 more related questions


Show fewer related questions

0



Leave a Reply

Your email address will not be published. Required fields are marked *