FetchType.LAZY不显示外键列

时间:2018-11-22 04:53:16

标签: java spring-boot fetch lazy-loading

我尝试在Spring Boot中使用FetchType.LAZY。但是,为什么即使执行的查询是FK列,FK列也不会显示在JSON中?这是我在控制台中打印的模型,控制器,存储库和执行的查询,以及邮递员中的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 - Foreign keys instead of Entities

已更新

这是最新的代码,但是根据@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 :(得分:0)

您有一个用@JsonIgnore注释的问题,它告诉杰克逊不要序列化该值,这就是它丢失的原因。

没有@JsonIgnore时出现错误的原因是,到JSON的序列化发生在事务之外,这将引发异常。在序列化之前将问题关系标记为FetchType.EAGER或在事务内部调用answer.getQuestion(),以便提取问题而不是将其作为代理。

您还可以将控制器注释为@Transactional,以便在事务内部进行序列化。