为了解释这个问题,让我从一个简单的 JSON 开始,演示我想保留在数据库中的一种可能结构。
JSON 表示一个
Questionnaire
对象,其中包含一个 Question
对象列表。每个Question
都有一个id、一个问题、一个类型和一个子问题列表。子问题可以是一个全新的问题(例如 ID 为“78b0de70-9d46-43a4-afad-90425f384ccf”的问题),也可以是现有问题(例如 ID 为“621883f8-8450-4101-8110-102c7148d42e”的问题) .
{
"questionnaire": {
"questions": [
{
"id": "8a776d93-50ee-4b09-b336-bfe746153ae4",
"question": "Question 1",
"type": "text",
"subQuestions": []
},
{
"id": "621883f8-8450-4101-8110-102c7148d42e",
"question": "Question 2",
"type": "number",
"subQuestions": []
},
{
"id": "6b8a9aa9-8cd5-4ea8-b8a7-97873dd4f3ea",
"question": "Question 3",
"type": "text",
"subQuestions": [
{
"id": "621883f8-8450-4101-8110-102c7148d42e", <<- repeated question
"question": "Question 2",
"type": "number",
"subQuestions": []
},
{
"id": "78b0de70-9d46-43a4-afad-90425f384ccf", <<- new question
"question": "Question 4",
"type": "text",
"subQuestions": []
}
]
}
]
}
}
对于实体类,我们有两个类
Questionnaire
和Question
如下。
@Entity
public class Questionnaire {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<Question> questions;
// Getter and setter omitted
}
@Entity
public class Question {
@Id
private String id;
private String question;
private String type;
@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@JoinTable(name = "question_next_questions")
private Collection<Question> subQuestions = Lists.newArrayList();
// Getters and setters omitted
}
现在反序列化和持久化上面的结构工作正常,但是当我尝试更新结构时我得到以下异常。
org.springframework.dao.InvalidDataAccessApiUsageException: Multiple representations of the same entity [com.example.entity.Question#621883f8-8450-4101-8110-102c7148d42e] are being merged. Detached: [com.example.entity.Question@7b3cb696]; Detached: [com.example.entity.Question@b5ce96e9];
我尝试通过从字段
CascadyType.MERGE
的级联操作中删除subQuestions
来解决这个问题并且它起作用了,但是当我尝试重新坚持上面的问卷时我得到以下异常。
org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find com.example.entity.Question with id 78b0de70-9d46-43a4-afad-90425f384ccf; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.example.entity.Question with id 78b0de70-9d46-43a4-afad-90425f384ccf
即ID为“78b0de70-9d46-43a4-afad-90425f384ccf”的新问题不再持久化
我需要在我的实体中更改什么才能像上面那样保存和更新结构?