我是spring MVC和JPA, hibernate的新手。我被这个错误困住了。我希望你的帮助朋友在我的项目中,我们正在使用春季MVC, hibernate, JPA, thymeleaf。我正在实现提问者形式,这是我的数据库脚本:
CREATE TABLE IF NOT EXISTS `assessments`(
`assessment_id` bigint(20) NOT NULL AUTO_INCREMENT,
`assessment_name` varchar(255) DEFAULT NULL,
`start_date` datetime DEFAULT NULL,
`end_date` datetime DEFAULT NULL,
PRIMARY KEY (`assessment_id`)
);
CREATE TABLE IF NOT EXISTS `questions`(
`question_id` bigint(20) NOT NULL AUTO_INCREMENT,
`question` varchar(255) DEFAULT NULL,
`assessment_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`question_id`),
KEY `fk_key1` (`assessment_id`),
CONSTRAINT `fk_key1` FOREIGN KEY (`assessment_id`) REFERENCES`assessments`(`assessment_id`) ON DELETE NO ACTION ON UPDATE NO ACTION);
CREATE TABLE IF NOT EXISTS `answers` (
`answer_id` bigint(20) NOT NULL AUTO_INCREMENT,
`answer` varchar(255) DEFAULT NULL,
`question_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`answer_id`),
KEY `fk_key2` (`question_id`),
CONSTRAINT `fk_key2` FOREIGN KEY (`question_id`) REFERENCES `questions` (`question_id`) ON DELETE NO ACTION ON UPDATE NO ACTION );
和模型层类
public class Assessments {
@Id
@SequenceGenerator(name = "assessmentGen", sequenceName = "assessment_generator")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "assessmentGen")
private long assessmentId;
@Column
private String assessmentName;
@Column
private Date startDate;
@Column
private Date endDate;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "assessmentId", fetch = FetchType.EAGER)
private List<Questions> questions = new ArrayList<Questions>();}
public class Questions {
@Id
@SequenceGenerator(name = "questionGen", sequenceName = "question_generator")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "questionGen")
private long questionId;
@Column
private String question;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "questionId", fetch = FetchType.EAGER)
private List<Answers> answers = new ArrayList<Answers>();
@ManyToOne(optional = false)
private Assessments assessmentId;
}
public class Answers {
@Id
@SequenceGenerator(name = "answersGen", sequenceName = "answers_generator")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "answersGen")
private long answerId;
@Column(name = "answer")
private String answer;
@ManyToOne(cascade = CascadeType.ALL)
private Questions questionId;
}
和my page in thymleaf
<form name="assessmentform" id="assessmentform" method="post"
th:action="@{/saveassessment}" th:object="${assessments}"
enctype="multipart/form-data">
<div id="sf1" class="frm">
<fieldset>
<legend>Assessment</legend>
<div class="form-group">
<label class="col-lg-2 control-label" for="assessment">Assessment
Name: </label>
<div class="col-lg-3">
<input type="text" placeholder="Name" id="assessmentName"
th:field="*{assessmentName}" class="form-control"
autocomplete="off" />
</div>
</div>
<div class="clearfix" style="height: 10px; clear: both;"></div>
<div class="form-group">
<label class="col-lg-2 control-label" for="startDate">Start
Date: </label>
<div class="col-lg-3">
<input type="text" id="startDate" th:field="*{startDate}"
class="form-control" autocomplete="off" />
</div>
</div>
<div class="clearfix" style="height: 10px; clear: both;"></div>
<div class="form-group">
<label class="col-lg-2 control-label" for="endDate">End
Date: </label>
<div class="col-lg-3">
<input type="text" id="endDate" th:field="*{endDate}"
class="form-control" autocomplete="off" />
</div>
</div>
<div class="clearfix" style="height: 10px; clear: both;"></div>
<div class="clearfix" style="height: 10px; clear: both;"></div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button class="btn btn-primary " type="button" id="addquestion"
name="addquestion">Add New Question</button>
<button class="btn btn-warning " type="button" id="remove"
name="remove">Remove Question</button>
</div>
</div>
<div id="templateWrapper">
<div class="questiontemplate">
<div class="clearfix" style="height: 10px; clear: both;"></div>
<label class="col-lg-2 control-label" for="question">Question
1: </label>
<textarea id="question" th:field="*{questions[0].question}"
cols="47" rows="3"></textarea><div class="clearfix" style="height: 10px; clear: both;"></div>
<label class="col-lg-2 control-label" for="question">Option
1: </label>
<input type="text" placeholder="option 1" id="option1" th:field="*{questions[0].answers[0].answer}"
autocomplete="off" size="50" /><div class="clearfix" style="height: 10px; clear: both;"></div>
<label class="col-lg-2 control-label" for="question">Option
2: </label>
<input type="text" placeholder="option 2" id="option2" th:field="*{questions[0].answers[1].answer}"
autocomplete="off" size="50" /><div class="clearfix" style="height: 10px; clear: both;"></div>
<label class="col-lg-2 control-label" for="question">Option
3: </label>
<input type="text" placeholder="option 3" id="option3" th:field="*{questions[0].answers[2].answer}"
autocomplete="off" size="50" /><div class="clearfix" style="height: 10px; clear: both;"></div>
<label class="col-lg-2 control-label" for="question">Option
4: </label>
<input type="text" placeholder="option 4" id="option4" th:field="*{questions[0].answers[3].answer}"
autocomplete="off" size="50" /><div class="clearfix" style="height: 10px; clear: both;"></div>
<div class="clearfix" style="height: 10px; clear: both;"></div>
</div>
</div>
<div class="clearfix" style="height: 10px; clear: both;"></div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button class="btn btn-primary open2" type="submit">Submit
</button>
</div>
</div>
</fieldset>
</div>
</form>
这是我的控制器
@RequestMapping(value = "/saveassessment", method = RequestMethod.POST)
public String saveassessmentForm(@ModelAttribute("Assessment") Assessments assessments, BindingResult assresult) {
try {
assessmentsService.saveAssessments(assessments);
}
catch (Exception e) {
System.out.println(e);
}
return "public_index";
}
当我试图将数据保存到数据库中时,它正在保存数据,但它没有显示关系,我的意思是问题表中的assessmentd列显示为空,而不是评估表的assessmentd,与答案表的questionId列相同为空。我想我漏掉了一些我能找到的东西。我希望我的错误是明确的
你没有发布所有相关代码,所以我猜。
在双向关联中,就像在评估和问题之间以及在问题和答案之间,你必须设置关联的两边。我的意思是,如果一个关联是双向的,你必须在链接的两边都有指针,而不是只有一个。
所以,在你的评估类中,你可能有一个方便的方法来帮助你做到这一点:
public class Assessments {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "assessmentId", fetch = FetchType.EAGER)
private List<Questions> questions = new ArrayList<Questions>();}
...
public void addQuestion(Questions question) {
question.setAssessmentId(this);
questions.add(question);
}
}
那么,在您的DAO中,您必须保存()两个对象:
Assessments assessments = new Assessments();
Questions question = new Question();
assessments.addQuestion(question); // Set both sides of the association
...
session.save(assessments);
session.save(question);
你必须调用save()两次,因为两个类都是实体,它们的实例有完全独立的生命周期。新对象是暂时的,如果您想将它们存储在数据库中,则必须将其持久化。如果它们是实体,它们的关系不会影响它们的生命周期。