FetchType.LAZY не показывает столбец внешнего ключа - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь использовать FetchType.LAZY с Spring Boot.Но почему столбец FK не отображается в JSON, даже если выполняется запрос - выбрать столбец FK?Вот моя модель, контроллер, репозиторий и выполненный запрос, которые напечатаны в консоли, а также результат JSON в виде почтальона

// AnswerModel
@Entity
@Table(name = "answers")
public class Answer implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String text;
    private Question question;
    private Date createdAt;
    private Date updatedAt;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "question_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JsonIgnore
    public Question getQuestion() {
        return question;
    }

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

// others getter and setter
}

// QuestionModel
@Entity
@Table(name = "questions")
public class Question implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String title;
    private String description;
    private Date createdAt;
    private Date updatedAt;

    // getters and setters
}

// AnswerController
@GetMapping("/answers")
    public List<Answer> getAllAnswer(){
        return answerRepository.findAll();
    }

// AnswerRepository
@Repository
@Transactional
public interface AnswerRepository extends JpaRepository<Answer, Long> {
}

// Query that executed when API hit in the postman
select
        answer0_.id as id1_0_,
        answer0_.created_at as created_2_0_,
        answer0_.question_id as question5_0_,
        answer0_.text as text3_0_,
        answer0_.updated_at as updated_4_0_ 
    from
        answers answer0_

// output JSON in postman (it did not show the question id, but the query did select the question_id column)
[
    {
        "id": 1,
        "text": "Please look into this github",
        "createdAt": "2018-11-22T03:55:48.865+0000",
        "updatedAt": "2018-11-22T03:55:48.865+0000"
    },
    {
        "id": 2,
        "text": "Please watch my youtube channel",
        "createdAt": "2018-11-22T03:55:57.642+0000",
        "updatedAt": "2018-11-22T03:55:57.642+0000"
    }
]

Итак, что здесь не так?Как показать question_id?Этот ответ действительно рекомендуется? Hibernate - Внешние ключи вместо сущностей

ОБНОВЛЕНО

Вот последний код, но, согласно ответу @Markoorn, я все еще не смог понятьгде я должен вызвать answer.getQuestion ();

// AnswerModel
@Entity
@Table(name = "answers")
public class Answer implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String text;
    private Question question;
    private Date createdAt;
    private Date updatedAt;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "question_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    public Question getQuestion() {
        return question;
    }

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

// others getter and setter
}

// QuestionModel
@Entity
@Table(name = "questions")
public class Question implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String title;
    private String description;
    private Date createdAt;
    private Date updatedAt;

    // getters and setters
}

// AnswerController
@Transactional
@GetMapping("/answers")
    public List<Answer> getAllAnswer(){
        return answerRepository.findAll();
    }

// AnswerRepository
@Repository
@Transactional
public interface AnswerRepository extends JpaRepository<Answer, Long> {
}

// Query executed
Hibernate: 
    select
        answer0_.id as id1_0_,
        answer0_.created_at as created_2_0_,
        answer0_.question_id as question5_0_,
        answer0_.text as text3_0_,
        answer0_.updated_at as updated_4_0_ 
    from
        answers answer0_
Hibernate: 
    select
        question0_.id as id1_1_0_,
        question0_.created_at as created_2_1_0_,
        question0_.description as descript3_1_0_,
        question0_.title as title4_1_0_,
        question0_.updated_at as updated_5_1_0_ 
    from
        questions question0_ 
    where
        question0_.id=?

// Error

2018-11-22 13:07:42.037 ERROR 5692 --- [nio-8080-exec-1] 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.http.converter.HttpMessageConversionException: 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.example.postgresdemo.model.Answer["question"]->com.example.postgresdemo.model.Question$HibernateProxy$DzJlWmh6["hibernateLazyInitializer"])] with root cause

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.example.postgresdemo.model.Answer["question"]->com.example.postgresdemo.model.Question$HibernateProxy$DzJlWmh6["hibernateLazyInitializer"])

1 Ответ

0 голосов
/ 22 ноября 2018

Ваш вопрос помечен @JsonIgnore, который говорит Джексону НЕ сериализовать это значение, поэтому оно отсутствует.

Причина, по которой вы получаете ошибку, когда у вас нет @JsonIgnore, естьпотому что сериализация в JSON происходит вне транзакции, которая выдает исключение.Либо пометить отношение вопроса как FetchType.EAGER, либо вызвать answer.getQuestion() внутри транзакции перед сериализацией, чтобы вопрос выбирался вместо того, чтобы быть прокси.

Вы также можете аннотировать свой контроллер как @Transactional, так что сериализацияпроисходит внутри транзакции.

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