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 中的 属性 名称。
我正在使用 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 中的 属性 名称。