我有一个 User
模型和a TodoItem
模型中 TodoItem
模型具有 User
带a的模型 user_id
@连接柱。我的问题是我从 getUsers
添加项后的api。它创建了这个超长的嵌套json,在这里它一次又一次地重复自己。我觉得我没有处理好主键的案子。
todocontroller.java文件
@RestController
@RequestMapping("/api")
public class TodoController {
@Autowired
private TodoRepository todoRepository;
@PostMapping("/addItem")
public TodoItem addTodoItem(@RequestBody TodoItem todoItem) {
return todoRepository.save(todoItem);
}
用户.java
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name")
private String name;
@Column(name = "password")
private String password;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<TodoItem> todos;
public User() {
}
public User(String name, String password, List<TodoItem> todos) {
this.name = name;
this.password = password;
this.todos = todos;
}
// setter and getters
todoitem.java文件
@Entity
@Table(name = "todo_item")
public class TodoItem {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "todo")
private String todo;
@Column(name = "completed")
private boolean completed;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
public TodoItem() {
}
public TodoItem(String todo, boolean completed) {
this.todo = todo;
this.completed = completed;
}
// setters and getters
添加项目请求
{
"todo": "blahblah",
"completed": false,
"user": {
"id": 6
}
}
添加项目响应
{
"id": 26,
"todo": "blahblah",
"completed": false,
"user": {
"id": 6,
"name": null,
"password": null,
"todos": null
}
}
所以我已经不喜欢给出响应的方式了,为什么name、pass和todos在id为6的用户存在时为null,而且我只是给它传递了一个todoitem,那么为什么todo为null。数据库填充正确,只是响应似乎错误。然后我认为这与我的主要问题有关,也就是这里;这是在我向用户添加项之后:
获取用户响应
[
{
"id": 6,
"name": "joe",
"password": "pass",
"todos": [
{
"id": 26,
"todo": "blahblah",
"completed": false,
"user": {
"id": 6,
"name": "joe",
"password": "pass",
"todos": [
{
"id": 26,
"todo": "blahblah",
"completed": false,
"user": {
"id": 6,
"name": "joe",
"password": "pass",
"todos": [
{
"id": 26,
"todo": "blahblah",
"completed": false,
"user": {
"id": 6,
"name": "joe",
"password": "pass",
"todos": [
{
"id": 26,
"todo": "blahblah",
"completed": false,
"user": {
"id": 6,
"name": "joe",
"password": "pass",
"todos": [
{
"id": 26,
"todo": "blahblah",
就这样持续了几千行。即使响应很疯狂,数据库也会正确更新,但是由于这个问题,api调用可能需要一段时间
2条答案
按热度按时间tzdcorbm1#
在todoitem.java中,删除user属性的getter。
确保todoitem.java中只有setter for user属性。
yptwkmov2#
本质上,当spring形成响应时,它正在执行一个类似“.tostring()”的方法,将实体Map到json对象以传递到前端。
你有一个
bidirectional
实体之间的关联,所以当Map器进入user
它绘制了所有的Maptodos
因为那些todos
所有人都和user
然后它得到user
…一次又一次…一次又一次的死亡循环。“最好的”方法和常见的方法是您应该创建一个dto类来构造它。
UserTodoDTO
:只要注意,如果你这样做了
log.info(user)
它也会做同样的事情。避免这种情况的方法(还有其他方法)是添加一个@JsonIgnore
或者重写todo的tostring()。更改为
TodoItem
```//Will not be mapped to JSON so stops the loop of death.
@JsonIgnore
//Lombok can make the toString() for you but need to
// tell it to ignore this field to stop loop of death.
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;