user1999453
user1999453

Reputation: 1423

Lombok and Spring Boot Issue - Unable to locate appropriate constructor on class

I have a base class as follows:

@Getter
@Setter
@SuperBuilder
abstract class Process {
    private String section;
    private String description;
}

The following class extends the Process class:

@Getter
@Setter
@SuperBuilder
public class OverdueProcessDTO extends Process {

    private int count;

/*    public OverdueProcessDTO(String section, String description, int count) {
        super(section, description);
        this.count = count;
    }*/
}

When I load my spring boot app the following execption is thrown:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [dummy.domain.dto.OverdueProcessDTO]. Expected arguments are: java.lang.String, java.lang.String, int [SELECT new dummy.domain.dto.OverdueProcessDTO (p.section, p.description, p.count) FROM dummy.domain.Test1 p 
WHERE p.labelDesc like ('%more than 1 hours') ORDER BY p.section ASC]

When I comment the @SuperBuilder in class Process and OverdueProcessDTO and also uncomment the constructor for OverdueProcessDTO it works fine. Any idea why I am getting the above error?

Upvotes: 1

Views: 957

Answers (1)

Mark Bramnik
Mark Bramnik

Reputation: 42491

Conceptually lombok works at compile time, so during the compilation it generates some code.

Using the above annotations leads to the situation where the constructor with The signature: public OverdueProcessDTO(String, String, int) is not generated.

Then, in runtime Hibernate seems to search for such a constructor and it doesn't find it hence the exception.

When you uncomment the hand-written constructor lombok won't generate anything that interferes with your "manual" definition, hence it works.

Now in terms of resolution: I suggest using a tool called "delombok" - it can show you what exactly was generated by lombok. So that you'll be able to check by yourself whether the constructor required by Hibernate exists or not.

Currently the java code generated by lombok for the DTO is:

public class OverdueProcessDTO extends Process {
    private int count;

    protected OverdueProcessDTO(OverdueProcessDTOBuilder<?, ?> b) {
        super(b);
        this.count = b.count;
    }

    public static OverdueProcessDTOBuilder<?, ?> builder() {
        return new OverdueProcessDTOBuilderImpl();
    }

    public int getCount() {
        return this.count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public static abstract class OverdueProcessDTOBuilder<C extends OverdueProcessDTO, B extends OverdueProcessDTO.OverdueProcessDTOBuilder<C, B>> extends Process.ProcessBuilder<C, B> {
        private int count;

        public B count(int count) {
            this.count = count;
            return self();
        }

        protected abstract B self();

        public abstract C build();

        public String toString() {
            return "OverdueProcessDTO.OverdueProcessDTOBuilder(super=" + super.toString() + ", count=" + this.count + ")";
        }
    }

    private static final class OverdueProcessDTOBuilderImpl extends OverdueProcessDTOBuilder<OverdueProcessDTO, OverdueProcessDTOBuilderImpl> {
        private OverdueProcessDTOBuilderImpl() {
        }

        protected OverdueProcessDTO.OverdueProcessDTOBuilderImpl self() {
            return this;
        }

        public OverdueProcessDTO build() {
            return new OverdueProcessDTO(this);
        }
    }
}

Upvotes: 1

Related Questions