вложенное исключение - org.hibernate.PropertyAccessException: не удалось установить значение поля - PullRequest
0 голосов
/ 12 апреля 2019

Я работаю над проектом Spring-boot 2, который используется для добавления вопросов, опций и ответов MCQ. Варианты могут варьироваться от 2 до 6 вариантов вопроса.

Я создал 3 таблицы: одну для Вопроса, одну для Вариантов и одну для Ответа.

Ниже моя модель в весеннем ботинке.

Я получаю сообщение об ошибке для OptionsModel и AnswerModel, когда получаю запрос в почтальоне.

Пожалуйста, помогите устранить ошибки и помогите мне улучшить мой код.

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 +
            '}';
}
}

Ошибка почтальона:

получить запрос на вопрос работает нормально.

GET запрос таблицы параметров:

{
"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 запрос таблицы ответов:

{
"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"
}

1 Ответ

2 голосов
/ 12 апреля 2019

Проблема с классом Answer

В вашем Answer классе вы используете неправильный тип поля в ваших отношениях. Отношения должны относиться к типу класса, к которому вы относитесь, а не к типу поля id.

Итак, ваш класс ответа должен быть таким:

@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() +
            '}';
}
}

Вложенное исключение

Как показано в этот вопрос: вы пытаетесь сериализовать дочерние объекты, пока связанные объекты не загружены (вы используете FetchType.LAZY).

У вас есть 2 варианта:

  • Вместо использования FetchType.LAZY используйте FetchType.EAGER (может быть не лучшим решением, если ваша база данных более сложная).

  • Аннотируйте классы Option и Question с помощью @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}). Это будет игнорировать сериализацию этих классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...