为什么我无法在通过 PUT/PATCH 路由关联后同时获得两个 Spring "many-to-many" 实体的信息?



我正在尝试使用多对多关联和 spring 将现有工作线程与现有任务相关联,但是当我使用 PUT/PATCH 路由时,无法使用 GET/tasks/{taskId} 或 GET/dev/{devId} 从(仅)这些项目中获取任何数据。

这是两个模型。工人模型:

@Entity
@Table(name = "Workers")
public class Worker implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String workerName;
private String passwd;
@RestResource(path = "/assocTask")
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinTable(name = "tasks_workers",
joinColumns = @JoinColumn(name = "worker_id",  referencedColumnName = "id",nullable = false, updatable = false),
inverseJoinColumns = @JoinColumn(name = "task_id", referencedColumnName = "id", nullable = false, updatable = false))
//@JsonManagedReference
private List<Task> tasks = new ArrayList<>();
public Worker() {
}
public Worker(String name, String password) {
this.workerName = name;
this.passwd = password;
}
public String getName() {
return workerName;
}
public void setName(String name) {
this.workerName = name;
}
public String getPassword() {
return passwd;
}
public void setPassword(String password) {
this.passwd = password;
}
public List<Task> getTasks() {
return tasks;
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
}
public Long getId() {
return id;
}
@Override
public String toString() {
return "Worker{" +
"id=" + id +
", workerName='" + workerName + ''' +
", passwd='" + passwd + ''' +
", tasks=" + tasks +
'}';
}
}

和任务模型:

@Entity
@Table(name = "Tasks")
public class Task implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String description;
@ManyToMany(mappedBy = "tasks", fetch = FetchType.LAZY)
@JsonBackReference
private List<Worker> workers = new ArrayList<>();
public Task() {
}
public Task(@NotNull String title, @NotNull String description) {
this.title = title;
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}

public List<Worker> getWorkers() {
return workers;
}
public void setWorkers(List<Worker> workers) {
this.workers = workers;
}
@Override
public String toString() {
return "Task{" +
"id=" + id +
", title='" + title + ''' +
", description='" + description + ''' +
", workers=" + workers +
'}';
}
}

这是我在获取/tasks/1 时遇到的错误,例如:

Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate java.util.Optional.toString()

来自服务实现以从数据库获取它:

@Override
public Task getTaskById(Long taskId) throws TaskNotFoundException {
if (taskId == null || taskId < 0) {
LOGGER.error("Invalid params received");
throw new Error("INVALID_ID");
}
return taskRepository.findById(taskId)
.orElseThrow(() -> new TaskNotFoundException(taskId, messageSource));
}

这是由休眠执行的查询:

select
tasks0_.worker_id as worker_id1_2_0_,
tasks0_.task_id as task_id2_2_0_,
task1_.id as id1_1_1_,
task1_.description as descript2_1_1_,
task1_.title as title5_1_1_ 
from
tasks_workers tasks0_ 
inner join
tasks task1_ 
on tasks0_.task_id=task1_.id 
where
tasks0_.worker_id=?

如果我在 Postgres 中运行它,我会得到预期的结果...... 好像在无限循环...但是是什么导致了溢出,为什么它没有在关联之前或之后发生?

有什么想法吗?

StackOverflowError

包含toString方法中发生的信息是否不够明显,无法找出问题?假设您在 ID 为 1 的工作线程上调用Worker.toString()。在Worker.toString()中,您tasks调用List.toString(),对于每个Task调用Task.toString()。在Task.toString()中,您将在输入无限递归的workers上调用List.toString(),因为连接到Worker的每个Task都是tasks列表的一部分,反之亦然,连接到Task的每个Worker都是workers列表的一部分。这是一个循环对象图。

简单的解决方案,只是不要调用可能具有反向引用的集合toString()。或者决定谁是"所有者",只打电话给拥有方的toString

相关内容

  • 没有找到相关文章

最新更新