简体   繁体   中英

Why json doesn't show objects in the list?

I'm doing a little pet project and can't solve this situation. Simply, I have 2 tables, one is ToDoBlock and another is ToDo with relation OneToMany. So, I created ToDoBlock using Post in httpClient from Idea and then I was added ToDo using another POST, but When I call my ToDoBlocks using GET it doesn't have list of my ToDos, it has but the array is empty.

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 all-blocks: (it works right)

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

JSON GET all-todos:

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

Controllers:

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

Response in the Postman:

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

]

Entity ToDo:

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

}

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

}

Please check my solution at https://github.com/ygor-sk/stackoverflow/tree/master/q53224496-many-to-one-not-in-json

The key is to explicitly save the new ToDo entity. It is not enough to add it to the collection in 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);
}

Another possibility would be to define a cascade, as mentioned here: JPA Updating Bidirectional Association

Additionally, I had to annotate the reference from ToDo to ToDoBlock with a @JsonIgnore annotation. Otherwise, I was getting a stackoverflow exception during serialization to JSON.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM