Home > Back-end >  Spring boot jooq dao trouble
Spring boot jooq dao trouble

Time:05-17

I'm new to Java and Spring and I am doing my first rest service. I've encountered a problem to which I cannot find an answer.

I generated entities using Jooq with pojos and daos

            <plugin>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-codegen-maven</artifactId>
            <version>3.16.6</version>
            <executions>
            ...
            </executions>
            <configuration>
                <jdbc>
                    <driver>org.postgresql.Driver</driver>
                    <url>jdbc:postgresql://localhost:5432/spring</url>
                    <user>postgres</user>
                    <password>${env.PGPASSWORD}</password>
                </jdbc>
                <generator>
                    <name>org.jooq.codegen.JavaGenerator</name>
                    <database>
                     ...
                    </database>
                    <target>
                        <packageName>com.example.otrtesttask.jooq</packageName>
                        <directory>target/generated-sources/jooq</directory>
                    </target>
                    <generate>
                        <pojos>true</pojos>
                        <daos>true</daos>
                        <records>true</records>
                    </generate>
                </generator>
            </configuration>
        </plugin>

My database structure:

CREATE TABLE branch(id    SERIAL PRIMARY KEY, title VARCHAR(100));

CREATE TABLE position(id    SERIAL PRIMARY KEY, title VARCHAR(30));

CREATE TABLE employee
(
    id          SERIAL PRIMARY KEY,
    manager_id  INTEGER REFERENCES employee (id),
    position_id INTEGER REFERENCES position (id) NOT NULL,
    full_name   VARCHAR(50)                      NOT NULL,
    branch_id   INTEGER REFERENCES branch (id)   NOT NULL);

CREATE TABLE task
(
    id          SERIAL PRIMARY KEY,
    priority    SMALLINT                     NOT NULL,
    description VARCHAR(200)                 NOT NULL,
    employee_id INT REFERENCES employee (id) NOT NULL);

Then I made Controller that calls Service that calls Repository to invoke CRUD operations. And it works perfectly fine, but I want to get position title along with id, etc. So I made a DTO:

@Data
public class EmployeeDto {
    private Integer id;
    private Integer managerId;
    private Integer positionId;
    private String fullName;
    private Integer branchId;
    private Employee manager;
    private Position position;
    private Branch branch;
}

After that I made a mapper that converts Employee to EmplyeeDto. I've been told that the best way to get nested data (like position title) is to use DAO fetchOnyById function.

@Service
public class MappingUtils {
    EmployeeDao employeeDao = new EmployeeDao();
    PositionDao positionDao = new PositionDao();
    BranchDao branchDao = new BranchDao();

    public EmployeeDto mapToEmployeeDto(Employee employee) {
        EmployeeDto dto = new EmployeeDto();

        dto.setId(employee.getId());
        dto.setBranchId(employee.getBranchId());
        dto.setPositionId(employee.getPositionId());
        dto.setFullName(employee.getFullName());
        dto.setManagerId(employee.getManagerId());

        dto.setManager(employeeDao.fetchOneById(employee.getManagerId()));
        dto.setPosition(positionDao.fetchOneById(employee.getPositionId()));
        dto.setBranch(branchDao.fetchOneById(employee.getBranchId()));
        return dto;
    }

And I map entities inside Repository like this:

   @Repository
   @RequiredArgsConstructor
   public class EmployeeRepository {
        @Autowired
        private final DSLContext dsl;
        private final MappingUtils mappingUtils;
        public List<EmployeeDto> findAll(Condition condition) {
            return dsl.selectFrom(Tables.EMPLOYEE)
                    .where(condition)
                    .fetchInto(Employee.class)
                    .stream().map(mappingUtils::mapToEmployeeDto)
                    .collect(Collectors.toList());
        }
    }

And it works fine until it gets to the dao fetch function. It throws an exception org.jooq.exception.DetachedException: Cannot execute query. No JDBC Connection configured. Once I remove the dao functions the get query returns nice response with manager, position and branch set to null.

What am I doing wrong here? And how to provide necessary connection?

==UPD== My application.properties:

spring.datasource.url=jdbc:postgresql://localhost:5432/spring
spring.datasource.username=postgres
spring.datasource.password=${PGPASSWORD}
spring.liquibase.change-log=classpath:liquibase/changelog.sql

CodePudding user response:

The problem is that your DAO classes aren't attached to a jOOQ Configuration. You just created them like this:

EmployeeDao employeeDao = new EmployeeDao();

But you have to create them like this:

EmployeeDao employeeDao = new EmployeeDao(configuration);

You can also configure the code generator to generate Spring annotations and then inject the DAOs to your class. The configuration would be:

<configuration>
  <generator>
    <generate>
      <springAnnotations>true</springAnnotations>
      <!-- ... -->

And then:

@Service
public class MappingUtils {
    @Autowired
    EmployeeDao employeeDao;
    @Autowired
    PositionDao positionDao;
    @Autowired
    BranchDao branchDao;
    // ...
  • Related