我尝试在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"])
答案 0 :(得分:0)
您有一个用@JsonIgnore
注释的问题,它告诉杰克逊不要序列化该值,这就是它丢失的原因。
没有@JsonIgnore
时出现错误的原因是,到JSON的序列化发生在事务之外,这将引发异常。在序列化之前将问题关系标记为FetchType.EAGER
或在事务内部调用answer.getQuestion()
,以便提取问题而不是将其作为代理。
您还可以将控制器注释为@Transactional
,以便在事务内部进行序列化。