简体   繁体   中英

nested exception is org.hibernate.PropertyAccessException: Could not set field value

I'm working on a Spring-boot 2 project which is used to added MCQ question, options and answer. Options may vary from 2 to 6 options for a question.

I have created 3 tables: one for Question, one for Options and one for Answer.

Below is my Model in Spring Boot.

I am getting error for OptionsModel and AnswerModel while I do get request in postman.

Please help to resolve errors and help me improve my code.

Question.java

@Entity
@Table(name = "mcq_question")
public class Question {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long questionId;

@Column(nullable = false)
private String question;

public Question() { }

public Long getQuestionId() {
    return questionId;
}

public void setQuestionId(Long questionId) {
    this.questionId = questionId;
}

public String getQuestion() {
    return question;
}

public void setQuestion(String question) {
    this.question = question;
}

@Override
public String toString() {
    return "Question{" +
            "questionId=" + questionId +
            ", question='" + question + '\'' +
            '}';
}
}

Options.java:

@Entity
@Table(name = "mcq_Options")
public class Option {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "option_id")
private int optionId;

private String option;

@ManyToOne(fetch = FetchType.LAZY, targetEntity = Question.class)
@JoinColumn(name = "questionId", nullable = false )
private Question questionId;

public Option() { }

public Option(String option, Question questionId) {
    this.option = option;
}

public int getOptionId() {
    return optionId;
}

public void setOptionId(int optionId) {
    this.optionId = optionId;
}

public String getOption() {
    return option;
}

public void setOption(String option) {
    this.option = option;
}

public Question getQuestionId() {
    return questionId;
}

public void setQuestionId(Question questionId) {
    this.questionId = questionId;
}

@Override
public String toString() {
    return "Option{" +
            "optionId=" + optionId +
            ", option='" + option + '\'' +
            ", questionId=" + questionId +
            '}';
}
}

Answer.java

@Entity
@Table(name = "mcq_answer")
public class Answer {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int answerId;

@OneToOne(fetch = FetchType.LAZY,  targetEntity = Question.class)
@JoinColumn(name = "questionId", nullable = false)
private int questionId;

@OneToOne(fetch = FetchType.LAZY,  targetEntity = Option.class)
@JoinColumn(name = "optionId", nullable = false)
private int optionId;

public Answer(){}

public Answer(int questionId, int optionId) {
    this.questionId = questionId;
    this.optionId = optionId;
}

public int getAnswerId() {
    return answerId;
}

public void setAnswerId(int answerId) {
    this.answerId = answerId;
}

public int getQuestionId() {
    return questionId;
}

public void setQuestionId(int questionId) {
    this.questionId = questionId;
}

public int getOptionId() {
    return optionId;
}

public void setOptionId(int optionId) {
    this.optionId = optionId;
}

@Override
public String toString() {
    return "Answer{" +
            "answerId=" + answerId +
            ", questionId=" + questionId +
            ", optionId=" + optionId +
            '}';
}
}

Postman error:

get request for question is working fine.

GET request for option table:

{
"timestamp": "2019-04-12T05:18:09.831+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Type definition error: [simple type, class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0]->com.bluepi.TrainingProject.model.Option[\"questionId\"]->com.bluepi.TrainingProject.model.Question$HibernateProxy$RND9ZBYW[\"hibernateLazyInitializer\"])",
"path": "/api/admin/viewmcqop"
}

GET request for answer table:

{
"timestamp": "2019-04-12T04:56:59.823+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Could not set field value [Option{optionId=2, option='option2', questionId=Question{questionId=1, question='Question1'}}] value by reflection : [class com.bluepi.TrainingProject.model.Answer.optionId] setter of com.bluepi.TrainingProject.model.Answer.optionId; nested exception is org.hibernate.PropertyAccessException: Could not set field value [Option{optionId=2, option='option2', questionId=Question{questionId=1, question='Question1'}}] value by reflection : [class com.bluepi.TrainingProject.model.Answer.optionId] setter of com.bluepi.TrainingProject.model.Answer.optionId",
"path": "/api/admin/viewmcqans"
}

Issue with the Answer class

In your Answer class you are using the wrong field type in your relationships. The relationship should be of the type of the class your are relating to and not the type of the id field.

So your Answer class should be like this instead:

@Entity
@Table(name = "mcq_answer")
public class Answer {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int answerId;

@OneToOne(fetch = FetchType.LAZY,  targetEntity = Question.class)
@JoinColumn(name = "questionId", nullable = false)
private Question questionId;

@OneToOne(fetch = FetchType.LAZY,  targetEntity = Option.class)
@JoinColumn(name = "optionId", nullable = false)
private Option optionId;

public Answer(){}

public Answer(Question questionId, Option optionId) {
    this.questionId = questionId;
    this.optionId = optionId;
}

public int getAnswerId() {
    return answerId;
}

public void setAnswerId(int answerId) {
    this.answerId = answerId;
}

public Question getQuestionId() {
    return questionId;
}

public void setQuestionId(Question questionId) {
    this.questionId = questionId;
}

public Option getOptionId() {
    return optionId;
}

public void setOptionId(Option optionId) {
    this.optionId = optionId;
}

@Override
public String toString() {
    return "Answer{" +
            "answerId=" + answerId +
            ", questionId=" + questionId.getQuestionId() +
            ", optionId=" + optionId.getOptionId() +
            '}';
}
}

Nested exception

As shown in this question: you are trying to serialize the children while the related objects are not loaded (you are using FetchType.LAZY ).

You have 2 options:

  • Instead of using FetchType.LAZY , use FetchType.EAGER (might not be the best solution if your database is more complex).

  • Annotate the Option and Question classes with @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) . This will ignore serialization of those classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM