我开发应用程序管理调查。使用@RestController执行POST方法以创建新Survey时出现错误
2020-02-19 18:10:34.257 ERROR 8648 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find pl.wsisiz.asp.domain.OptionGroup with id 1; nested exception is javax.persistence.EntityNotFoundException: Unable to find pl.wsisiz.asp.domain.OptionGroup with id 1] with root cause
javax.persistence.EntityNotFoundException: Unable to find pl.wsisiz.asp.domain.OptionGroup with id 1
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:163) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:216) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:332) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:108) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:74) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
at ...
.....
由于错误为unable to find optionGroupId
,我认为该问题可能与Question和OptionGroup之间的关系有关。选项组可用于许多问题中,但问题始终具有1个或没有选项组。
模型-Question.java
package pl.wsisiz.asp.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.LinkedHashSet;
import java.util.Set;
@Entity
@Table(name = "questions")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Question {
@Id
@GeneratedValue
@Column(name = "question_id")
private Integer questionId;
//other fields
...
@ManyToOne
@JoinColumn(name = "option_group_id")
// @NotFound(action = NotFoundAction.IGNORE) //with this line there is no error
// and optionGroup is always null
private OptionGroup optionGroup;
}
模型-OptionGroup.java
package pl.wsisiz.asp.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.LinkedHashSet;
import java.util.Set;
@Entity
@Table(name = "option_groups")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class OptionGroup {
@Id
@GeneratedValue
@Column(name = "option_group_id")
private Integer optionGroupId;
//other fields
// ...
@OneToMany(mappedBy = "optionGroup", cascade = {CascadeType.ALL})
@JsonIgnore
private Set<Question> questions = new LinkedHashSet<>();
}
在执行POST方法时,Controller使用addSurvey(@RequestBody SurveyTemplate surveyTemplate)
。 SurveyTemplate是通过save()
方法从JpaRepository保存的。
调用此POST方法,我将使用GET方法接收到的JSON放在正文中(此后,我删除了数据库内容)。我放在正文中的JSON看起来像这样:
{
"surveyTemplateId": 1,
"surveyName": "Example survey",
"instructions": null,
"otherInfo": null,
"surveySections": [
{
"surveySectionId": 1,
"sectionName": "Metric",
"questions": [
{
"questionId": 1,
"questionName": "Age:",
"answerRequired": true,
"inputType": "CHOICE",
"subquestions": [],
"optionGroup": {
"optionGroupId": 1,
"optionGroupName": "age20-25+",
"optionChoices": [
{
"optionChoiceId": 1,
"optionChoiceName": "less than 20"
},
{
"optionChoiceId": 2,
"optionChoiceName": "20"
},
{
"optionChoiceId": 3,
"optionChoiceName": "21"
},
{
"optionChoiceId": 4,
"optionChoiceName": "22"
},
{
"optionChoiceId": 5,
"optionChoiceName": "23"
},
{
"optionChoiceId": 6,
"optionChoiceName": "24"
},
{
"optionChoiceId": 7,
"optionChoiceName": "more than 25"
}
]
}
}
]
}
]
}
编辑:
当我用多对多关系代替多对一关系(在图中标记)时,一切正常。您可以查看此更改之前的整个ERD。但是,我实际上不知道为什么它不适用于多对一关系,以及是否有一种方法可以实现多对一关系。