遇到 JPA Hibernate 中 @OneToMany 和 @ManyToOne 导致无限递归问题。

huangapple go评论71阅读模式
英文:

getting infinite recursion with JPA hibernate by @OneToMany and @ManyToOne

问题

我有一个无法解决的问题,我也尝试过使用JsonIgnore,但也没有起作用。
我有一个待办事项列表,我希望我的任务能输出我给它们的UserID。问题是,因为每个用户都有一个Task数组,所以任务给我提供了无限循环的任务和用户。

以下是我的代码:

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;

然后我有普通的getter和setter方法以及一个toString方法。

英文:

I have a problem that I can't solve, I tried it with JsonIgnore too, but it didn't work either.
I have a ToDo list, and I want my tasks to output the UserID I gave to them. The problem is because every user has a Task array, the tasks are giving me an infinite loop of tasks and users.

遇到 JPA Hibernate 中 @OneToMany 和 @ManyToOne 导致无限递归问题。

that's my Code:

User:

@Entity
public class User {

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

private String name;

@OneToMany(mappedBy = &quot;user&quot;, cascade = CascadeType.ALL)
private Set&lt;Task&gt; 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 = &quot;user_id&quot;, nullable = false)
private User user;

then I have normal getter and setter and a toString method.

答案1

得分: 5

使用 @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;
}
英文:

Use @JsonManagedReference and @JsonBackReference

User:

@Entity
public class User {

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

private String name;

@OneToMany(mappedBy = &quot;user&quot;, cascade = CascadeType.ALL)
@JsonManagedReference
private Set&lt;Task&gt; tasks;

Task :

@Entity
public class Task {

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

private String name;

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

答案2

得分: 1

在反序列化过程中,@OneToMany或@ManyToOne关系字段也被称为。最好为响应创建响应类,而不是实体类,并在其中设置您的实体值。

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
}
英文:

In deserialization @OneToMany or @ManytoOne Relation field are also called.
It's better to create response class for response rather than entity class and set your entity value in it.

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
}

答案3

得分: 0

尝试使用以下注解:

//--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;
英文:

Try with the following annotations:

//--1
@OneToMany(mappedBy = &quot;user&quot;, cascade = {CascadeType.ALL})
@JsonManagedReference
private Set`&lt;Task&gt;` tasks;

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

答案4

得分: 0

我个人不喜欢混合处理数据库表示和序列化的责任。在JPA中拥有一个双向图是完全可以的,唯一的问题是当你想要将这个双向图序列化成单向树结构时会出现问题,这就是为什么我会根据你的用例创建一个第二个表示来表示单向树:要么拥有一个“任务”对象,其中包含一个浅层次的“用户”对象,其中包含你在任务上下文中需要的确切值,要么拥有一个“用户”对象,其中包含一个包含在用户上下文中需要的确切值的浅层次的“任务”对象列表。

英文:

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.

答案5

得分: -1

我找到了解决方案,
我必须将我的getUser()方法更改为:

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

现在,我仅从任务中获取userId,而不是从用户获取所有内容,这就是为什么我不再遇到递归的问题。

我希望现在我能够帮助未来遇到这个问题的人,他们在互联网上找不到任何解决方案。

遇到 JPA Hibernate 中 @OneToMany 和 @ManyToOne 导致无限递归问题。

英文:

I found the solution,
i had to change my getUser() method to:

    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.

遇到 JPA Hibernate 中 @OneToMany 和 @ManyToOne 导致无限递归问题。

I hope I can help now future people that have this problem too and don't find any solution on the internet

huangapple
  • 本文由 发表于 2020年4月8日 14:49:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/61094824.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定