Why hibernate make so much queries even while using DTO and LAZY LOADING?

I have Entity class Employee :

@Entity
@NoArgsConstructor(force = true)
@AllArgsConstructor
@Builder
@Data
@Table(name = "employee")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    @Column(name = "employee_id")
    private UUID employeeId;

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

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

    @ManyToOne( cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToMany(mappedBy = "employees", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private Set<Equipment> tools;

    @ManyToMany(mappedBy = "employees", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private Set<Training> trainings;

and User entity class

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@Table(name = "user_account")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    @Column(name = "user_id")
    private UUID id;

    @NotBlank
    @Length(min =3)
    @Column(name = "name")
    private String name;

    @NotBlank
    @Length(min =6)
    @Column(name = "password")
    private String password;
    @NotBlank
    @Pattern(regexp = "^(.+)@(.+)$")
    @Column(name = "email",unique = true)
    private String email;

    @OneToMany(mappedBy = "user")
    private Set<Equipment> tools;

    @OneToMany(mappedBy = "user")
    private Set<Training> trainings;


    @OneToMany(mappedBy = "user")
    private Set<Employee> employees;

    @OneToMany(mappedBy = "user")
    private Set<Car> cars;

Service class:

 @Transactional
    public Employee getEmployee(UUID employeeUUID) {
        return employeeRepository.findEmployeeByEmployeeId(employeeUUID).orElseThrow(() -> new EntityNotFoundException("Employee not found"));
    }

Repository DAO

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, UUID> {
    Optional<Employee> findEmployeeByEmployeeId(UUID employeeId);

}

While I am trying to return the Employee entity from database response time is 1 second

This is how the response looks like:

{
    "employeeId": "935ad5a2-34cb-4b27-8706-7d07fc283c84",
    "name": "2",
    "surname": "2",
    "user": {
        "id": "694b1eb9-622b-4333-84d2-69e7e1f96a33",
        "name": "Correct",
        "password": "$2a$10$tb.5rVD0PGpU1P99tCtrJufz.ONZC8hg6D1fgjAkVyGDJQq92YeV.",
        "email": "correct@correct.com",
        "tools": [],
        "trainings": [],
        "employees": [],
        "cars": [],
        "enabled": true,
        "username": "correct@correct.com",
        "authorities": null,
        "accountNonLocked": true,
        "accountNonExpired": true,
        "credentialsNonExpired": true
    },
    "tools": [],
    "trainings": [
        {
            "trainingId": "065a1019-ebc9-406d-8c24-fcd77ca51054",
            "name": "Training1",
            "description": "Training",
            "employees": [],
            "user": {
                "id": "694b1eb9-622b-4333-84d2-69e7e1f96a33",
                "name": "Correct",
                "password": "$2a$10$tb.5rVD0PGpU1P99tCtrJufz.ONZC8hg6D1fgjAkVyGDJQq92YeV.",
                "email": "correct@correct.com",
                "tools": [],
                "trainings": [],
                "employees": [],
                "cars": [],
                "enabled": true,
                "username": "correct@correct.com",
                "authorities": null,
                "accountNonLocked": true,
                "accountNonExpired": true,
                "credentialsNonExpired": true
            }
        }
    ]
}

config:

spring:
  jackson:
    serialization:
      fail-on-empty-beans: false
  datasource:
    url: 
    username:
    password: 
    driver-class-name: org.postgresql.Driver
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: true
    properties:
      hibernate:
        format_sql: true
    database: postgresql
    open-in-view: false

  flyway:
    baseline-on-migrate: true
myapp:
  secretKey: ""






I was trying to map Employee to DTO class but it didn’t help.

   @Transactional
    public EmployeeDTO getEmployee(UUID employeeUUID) {
        Employee employee = employeeRepository.findEmployeeByEmployeeId(employeeUUID)
                .orElseThrow(() -> new EntityNotFoundException("Employee not found"));

        return EmployeeDTO.builder()
                .uuid(employee.getEmployeeId())
                .name(employee.getName())
                .surname(employee.getSurname())
                .build();
    }

even while using native query it keeps making too much queries and response doesnt change

 @Query(value = "SELECT * FROM Employee WHERE employee_id= :employeeId",nativeQuery = true)
    Optional<Employee> findEmployeeByEmployeeId(UUID employeeId);

I was trying different approaches with join fetch (but it seems useless because i want data from only one table)

@Query(value = "SELECT new com.example.EquipmentApi.dto.EmployeeDTO(e.employeeId, e.name, e.surname) FROM Employee e WHERE e.employeeId = :employeeId")
Optional\<EmployeeDTO\> findEmployeeByEmployeeId(@Param("employeeId") UUID employeeId);

Only thing which worked is returning DTO directly from repository. But I am not sure if this is a correct approach.

Why I get all information about user while I have fetch type lazy set in all entities ? Also i don’t use user in service class except @AuthenticationPrincipal User user in controller class.
Is it normal behaviour for JPA/HIBERNATE to return all relations for entity while using lazy loading?
What can I do to reduce number of queries ? I got 200 hibernate queries in console (I have show-sql: true in properties)

I guess you might be initializing some association unknowingly. Either way, to rule out Spring Data being the problem, please try to create a reproducer with our test case template and if you are able to reproduce the issue, create a bug ticket in our issue tracker and attach that reproducer.