这个问题在这里已经有答案了:
保存对象的tostring值时发生stackoverflow错误-java/hibernate/spring(2个答案)
18天前关门了。
我正在尝试使用多对多关联和spring将现有的worker与现有的任务关联起来,但是当我使用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));
}
这是hibernate执行的查询:
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中运行它,我会得到预期的结果。。。好像它在无限循环。。。但是,是什么导致了溢出,为什么它不发生在协会之前或之后打破它?
有什么想法吗?
1条答案
按热度按时间vdzxcuhz1#
是一个
StackOverflowError
有了发生在toString
方法对你来说不够明显,不足以解决问题?假设你打电话来Worker.toString()
在id为1的工作进程上。在Worker.toString()
你打电话来List.toString()
在tasks
每一个Task
电话Task.toString()
. 在Task.toString()
你再打给我List.toString()
在workers
这就是你进入无限递归的地方,因为Task
连接到Worker
是这个计划的一部分tasks
列表和其他方式,每Worker
连接到Task
是这个计划的一部分workers
列表。这是一个循环对象图。简单的解决办法,就是不要打电话
toString()
在可能有反向引用的集合上。或者决定谁是“主人”并且只打电话toString
在拥有方。