首页 > 解决方案 > Lombok 和 Spring Boot 问题 - 无法在类上找到适当的构造函数

问题描述

我有一个基类如下:

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

以下类扩展了 Process 类:

@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;
    }*/
}

当我加载我的 spring boot 应用程序时,会抛出以下 execption:

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]

当我在类 Process 和 OverdueProcessDTO 中评论 @SuperBuilder 并取消注释 OverdueProcessDTO 的构造函数时,它工作正常。知道为什么我会收到上述错误吗?

标签: spring-bootspring-datalombok

解决方案


从概念上讲,lombok 在编译时工作,因此在编译期间它会生成一些代码。

使用上述注解会导致public OverdueProcessDTO(String, String, int)没有生成带有 The signature: 的构造函数的情况。

然后,在运行时 Hibernate 似乎在搜索这样的构造函数,但没有找到它,因此出现了异常。

当您取消注释时,手写构造函数 lombok 不会生成任何干扰您的“手动”定义的内容,因此它可以工作。

现在就分辨率而言:我建议使用一个名为“delombok”的工具 - 它可以向您展示 lombok 究竟生成了什么。这样您就可以自己检查 Hibernate 所需的构造函数是否存在。

目前lombok为DTO生成的java代码为:

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);
        }
    }
}

推荐阅读