【问题标题】:Why json doesn't show objects in the list?为什么json不显示列表中的对象?
【发布时间】:2018-11-09 11:03:09
【问题描述】:

我正在做一个小宠物项目,无法解决这种情况。简单地说,我有 2 张表,一张是 ToDoBlock,另一张是 ToDo,关系为 OneToMany。因此,我在 Idea 的 httpClient 中使用 Post 创建了 ToDoBlock,然后使用另一个 POST 添加了 ToDo,但是当我使用 GET 调用我的 ToDoBlocks 时,它没有我的 ToDos 列表,它有但数组为空。

JSON 发布 ToDoBlock:

POST http://localhost:8080/todos/create-todo-block
Content-Type: application/json

{
 "name" : "block2"
}

JSON 后待办事项:

POST http://localhost:8080/todos/create-simple-todo/1
Content-Type: application/json

{
 "text" : "my third todo"
}

JSON GET all-blocks:(它工作正常)

GET http://localhost:8080/todos/get-all-blocks
Content-Type: application/json

JSON 获取所有待办事项:

GET http://localhost:8080/todos/find-all-todos
Content-Type: application/json

控制器:

@PostMapping(value = "/create-todo-block")
@ResponseStatus(HttpStatus.CREATED)
public void createToDoBlock(@RequestBody ToDoBlock toDoBlock){
    toDoService.saveToDoBlock(toDoBlock);
}

@PostMapping(value = "/create-simple-todo/{blockId}")
@ResponseStatus(HttpStatus.CREATED)
public void createToDo(@PathVariable long blockId, @RequestBody String text){
    toDoService.saveSimpleToDo(text, blockId);
}

道:

@Override
public void saveToDoBlock(ToDoBlock toDoBlock) {
    entityManager.persist(toDoBlock);
}

@Override
public void saveSimpleToDoByBlockId(String text, long blockId) {
    ToDo toDo = new ToDo(text);
    ToDoBlock block = entityManager.getReference(ToDoBlock.class, blockId);
    block.addToDo(toDo);
    entityManager.persist(block);
}

邮递员的回应:

[
{
    "id": 1,
    "name": "block",
    "archive": null,
    "toDos": []
}

]

实体待办事项:

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(of = "id")
@Entity
@Table(name = "todo")
public class ToDo {

@Id
@GeneratedValue
private Long id;

@Column (nullable = false)
private String text;

@Column
private Scaryness scaryness;

@Column
private Hardness hardness;

@Column
private boolean ready;

@Column
private LocalDateTime createdOn;

@ManyToOne
@JoinColumn(name = "todo_block_id")
private ToDoBlock toDoBlock;

public ToDo(String text, ToDoBlock todoBlock) {
    this.text = text;
    this.toDoBlock = todoBlock;
    this.ready = false;
    this.createdOn = LocalDateTime.now();
}

}

实体 ToDoBlock:

@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
@Setter
@Getter
@Entity
@Table(name = "todo_block")
public class ToDoBlock {

@Id
@GeneratedValue
private Long id;

@Column(name = "name")
private String name;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "archive_id")
private Archive archive;

@Setter(AccessLevel.PRIVATE)
@OneToMany(mappedBy = "toDoBlock")
private List<ToDo> toDos = new ArrayList<>();

public void addToDo(ToDo toDo){
    toDos.add(toDo);
    toDo.setToDoBlock(this);
}

public void removeToDo(ToDo toDo){
    toDos.remove(toDo);
    toDo.setToDoBlock(null);
}

}

【问题讨论】:

  • 您还没有展示如何从 db 中读取数据并构建您的 json?
  • 没错。我们至少需要查看您的@Entity 类。
  • 哦,对不起。添加了实体和 GET(在 POST 之后)。
  • 我想为您提供更多帮助,但您的代码甚至无法编译。 ToDo toDo = new ToDo(文本); -> 没有这样的构造函数。
  • 你能把你的整个代码放到一个github仓库吗?

标签: java json hibernate


【解决方案1】:

请在https://github.com/ygor-sk/stackoverflow/tree/master/q53224496-many-to-one-not-in-json查看我的解决方案

关键是显式保存新的 ToDo 实体。将其添加到 ToDoBlock 中的集合是不够的。

public void saveSimpleToDoByBlockId(String text, long blockId) {
    ToDoBlock block = entityManager.getReference(ToDoBlock.class, blockId);
    ToDo toDo = new ToDo(text, block);
    block.addToDo(toDo);
    entityManager.persist(toDo); // <----- persist ToDo too
    entityManager.persist(block);
}

另一种可能性是定义级联,如下所述:JPA Updating Bidirectional Association

此外,我必须使用 @JsonIgnore 注释来注释从 ToDo 到 ToDoBlock 的引用。否则,我在序列化为 JSON 期间遇到了 stackoverflow 异常。

@JsonIgnore
@ManyToOne
@JoinColumn(name = "todo_block_id")
private ToDoBlock toDoBlock;

【讨论】:

  • 它确实有效,但没有@JsonIgnore 则无效。需要检查此注释在做什么,因为没有它,我的 Get 请求会在邮递员中显示无限数量的待办事项。
  • @JsonIgnore 告诉 JSON 序列化库 (jackson) 不要将带注释的字段打印到输出。在这种情况下,ToDo 包含对 ToDoBlock 的引用,反之亦然。 Jackson 遵循对象图,在这种情况下,它包含一个无限循环。在我的例子中,这表现为 StackOverflowException。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-05
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 2021-03-05
  • 1970-01-01
  • 2022-12-04
相关资源
最近更新 更多