Почему json не показывает объекты в списке? - PullRequest
0 голосов
/ 09 ноября 2018

Я занимаюсь маленьким любимым проектом и не могу решить эту ситуацию. Просто у меня есть 2 таблицы, одна ToDoBlock и другая ToDo с отношением OneToMany. Итак, я создал ToDoBlock с помощью Post в httpClient из Idea, а затем я добавил ToDo с помощью другого POST, но когда я вызываю ToDoBlocks с помощью GET, у него нет списка моих задач, он есть, но массив пуст.

JSON Post ToDoBlock:

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

{
 "name" : "block2"
}

JSON Post ToDo:

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

{
 "text" : "my third todo"
}

JSON GET для всех блоков: (работает правильно)

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

DAO:

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

}

1 Ответ

0 голосов
/ 09 ноября 2018

Пожалуйста, проверьте мое решение на 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

Кроме того, мне пришлось аннотировать ссылку из ToDo в ToDoBlock с аннотацией @JsonIgnore. В противном случае я получал исключение stackoverflow во время сериализации в JSON.

@JsonIgnore
@ManyToOne
@JoinColumn(name = "todo_block_id")
private ToDoBlock toDoBlock;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...