简体   繁体   English

通过@OneToMany 和@ManyToOne 使用 JPA hibernate 获得无限递归

[英]getting infinite recursion with JPA hibernate by @OneToMany and @ManyToOne

I have a problem that I can't solve, I tried it with JsonIgnore too, but it didn't work either.我有一个无法解决的问题,我也用 JsonIgnore 尝试过,但也没有用。 I have a ToDo list, and I want my tasks to output the UserID I gave to them.我有一个待办事项列表,我希望我的任务是 output 我给他们的用户 ID。 The problem is because every user has a Task array, the tasks are giving me an infinite loop of tasks and users.问题是因为每个用户都有一个任务数组,这些任务给了我一个无限循环的任务和用户。

在此处输入图像描述

that's my Code:那是我的代码:

User:用户:

@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

private String name;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private Set<Task> tasks;

Task:任务:

@Entity
public class Task {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

private String name;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", nullable = false)
private User user;

then I have normal getter and setter and a toString method.然后我有普通的 getter 和 setter 以及一个 toString 方法。

Use @JsonManagedReference and @JsonBackReference使用 @JsonManagedReference 和 @JsonBackReference

User:用户:

@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

private String name;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@JsonManagedReference
private Set<Task> tasks;

Task:任务:

@Entity
public class Task {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

private String name;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
@JsonBackReference
private User user;

In deserialization @OneToMany or @ManytoOne Relation field are also called.在反序列化中,@OneToMany 或 @ManytoOne 关系字段也被调用。 It's better to create response class for response rather than entity class and set your entity value in it.最好为响应创建响应 class 而不是实体 class 并在其中设置您的实体值。

public class TaskResponse {
    private int id;
    private String name;
    private UserResponse user;
    ...setter getter
}
public class UserResponse {
   private int id;
   private String name;
   ...setter getter
}

Try with the following annotations:尝试使用以下注释:

//--1
@OneToMany(mappedBy = "user", cascade = {CascadeType.ALL})
@JsonManagedReference
private Set`<Task>` tasks;

//--2
**@ManyToOne(cascade = CascadeType.ALL)**
@JoinColumn(name = "user_id")
@JsonBackReference
private User user;

I found the solution, i had to change my getUser() method to:我找到了解决方案,我不得不将我的 getUser() 方法更改为:

    public int getUser() {
    return user.getId();
}

now I get only the userId from the task and not everything from the User, that's why I don't get a recursion anymore.现在我只从任务中获取 userId 而不是从用户那里获取所有内容,这就是我不再获得递归的原因。

在此处输入图像描述

I hope I can help now future people that have this problem too and don't find any solution on the internet我希望我现在可以帮助将来也有这个问题并且在互联网上找不到任何解决方案的人

I personally don't like mixing up responsibilities like database representation and serialization.我个人不喜欢混淆数据库表示和序列化等职责。 It is totally fine to have a bidirectional graph in JPA, the only problem arises when you want to serialize this bidirectional graph into a unidirectional tree structure, that's why I would create a second representation for the unidirectional tree depending on your use-case: Either have a "task" with a shallow "user" object containing exactly those values you need in the context of a task or having a "user" with a list of shallow "task" objects containing exactly those values you need in the context of a user.在 JPA 中有一个双向图是完全可以的,唯一的问题是当您想将此双向图序列化为单向树结构时,这就是为什么我会根据您的用例为单向树创建第二个表示:有一个带有浅“用户” object 的“任务”,其中包含您在任务上下文中需要的那些值,或者有一个“用户”,其中包含一个浅“任务”对象列表,其中恰好包含您在一个上下文中需要的那些值用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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