Spring 引导 - 使用 Lombok 时 Rest 控制器返回空对象

Spring Boot - Rest Controller is returning empty object when using Lombok

我正在使用 Spring Boot 2.1.4 和 Gradle 5.0 开发一个简单的 Rest API。我正在使用 Lombok v1.18.6 构建我的 classes 但是当我调用服务时我收到一个空对象

我尝试手动添加 getters 和 setters 方法并解决了问题,但我想知道为什么 lombok 在我的项目中不起作用。

此外,我的 IDE 正在正确识别 lombok 插件。我正在使用 IntelliJ IDEA

我的 gradle 依赖项:

    compileOnly 'org.projectlombok:lombok:1.18.6'
    annotationProcessor 'org.projectlombok:lombok:1.18.6'

我的模型class:

@Entity
@Data
public class Category implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id_category")
    private int idCategory;

    @NotBlank
    private String name;

    @OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private List<Language> languages;
}

我的 RestController:

@RestController
@RequestMapping("/categories")
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    @GetMapping
    public ResponseEntity<List<Category>> findAllCategories(){
        List<Category> categories = categoryService.findAll();
        return new ResponseEntity<List<Category>>(categories, HttpStatus.OK);
    }
}

我收到了这个回复:

[
    {
        "languages": []
    }
]

但我希望收到的是:

[
    {
        "idCategory": 1,
        "name": "Backend" 
        "languages": []
    }
]

实际上,我觉得奇怪的是,唯一显示的属性是 languages,它有 @JsonProperty 注释,为什么会这样?

更新

我刚刚意识到我的 IDE (IntelliJ) 正在识别 lombok 插件并且我也启用了注释处理但是当我尝试使用 getter 或 setter,它会抛出一个错误:

Error:(18, 26) java: cannot find symbol
  symbol:   method setName(java.lang.String)
  location: class com.ramonparis.cvmanager.model.Category

我怀疑 Hibernate 不喜欢 Lombok 自动生成的完整 equals。你应该试试:

@Entity
@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Category implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @EqualsAndHashCode.Include
    @Column(name = "id_category")
    private int idCategory;

Hibernate 期望其上下文缓存与主键匹配,但 Lombok 生成匹配所有字段的 Equals,这意味着实体中的单个更改将破坏缓存并可能阻止正确加载实体。

这可能是由于 categoryService.findAll(); 具有不同的映射名称。

例如对于 idCategory,结果有 id_category。由于这个 id_category 没有被映射到 idCategory.

所以你可以使用,

@JsonProperty("idCategory")

它可能对您不起作用的原因是,如果您的项目未设置为将 IDE 构建委派给 Gradle,并且未为该项目启用注释处理,或者以某种方式配置错误。
设置 -> 构建、执行、部署 -> 构建工具 - Gradle -> 运行器
设置 -> 构建、执行、部署 -> 编译器 -> 注释处理器

您是否尝试过从命令行构建 运行 Gradle 以排除 IntelliJ 中的错误配置?

确保启用选项注释处理,重新运行你的项目就是这样

你可以使用这个注解

@JsonProperty("idCategory")

@JsonProperty 注释以指示 JSON 中的 属性 名称。