关于Hibernate中的FetchType.EAGER
1.先定义两个model:Question和Answer,每个Question对应多个Answer;
Question.java
package lan.study.hibernate.model; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; @Entity public class Question { private Integer id; private String question; private Set<Answer> answers; @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getQuestion() { return question; } public void setQuestion(String question) { this.question = question; } @OneToMany(mappedBy="question", cascade=CascadeType.ALL, fetch=FetchType.EAGER) public Set<Answer> getAnswers() { return answers; } public void setAnswers(Set<Answer> answers) { this.answers = answers; } }
Answer.java
package lan.study.hibernate.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; @Entity public class Answer { private Integer id; private String answer; private Question question; @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAnswer() { return answer; } public void setAnswer(String answer) { this.answer = answer; } @ManyToOne @JoinColumn(name = "question_id") public Question getQuestion() { return question; } public void setQuestion(Question question) { this.question = question; } }
2.当OneToMany中加上 fetch=FetchType.EAGER时,查询时会把关联的对象全部加载到内存中,即使使用setFetchMode,也不起作用,而去掉fetch=FetchType.EAGER时,setFetchMode才起作用。
@OneToMany(mappedBy="question", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
publicSet<Answer>getAnswers(){
returnanswers;
}3.测试代码
package lan.study.hibernate.model; import java.util.HashSet; import java.util.List; import java.util.Set; import lan.study.hibernate.util.HibernateUtil; import org.hibernate.Criteria; import org.hibernate.FetchMode; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.criterion.CriteriaSpecification; import org.junit.Test; public class QuestionTestCase { @Test public void testSaveQuestion(){ Question question = new Question(); question.setQuestion("question."); Answer answerA = new Answer(); answerA.setAnswer("answerA"); answerA.setQuestion(question); Answer answerB = new Answer(); answerB.setAnswer("answerB"); answerB.setQuestion(question); Answer answerC = new Answer(); answerC.setAnswer("answerC"); answerC.setQuestion(question); Set<Answer> answers = new HashSet<Answer>(); answers.add(answerA); answers.add(answerB); answers.add(answerC); question.setAnswers(answers); Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.save(question); session.getTransaction().commit(); session.close(); } @Test public void getQuestionByCriteria(){ Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Criteria c = session.createCriteria(Question.class); c.setFetchMode("answers", FetchMode.JOIN); c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); @SuppressWarnings("unchecked") List<Question> questions = c.list(); session.getTransaction().commit(); System.out.println(questions.size()); for (Question question : questions) { for(Answer answer : question.getAnswers()){ System.out.println(answer.getAnswer()); } } } @Test public void getQuestionByHQL(){ Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); String hql = "select distinct(q) from Question q inner join fetch q.answers where q.id=1"; Query q = session.createQuery(hql); @SuppressWarnings("unchecked") List<Question> questions = q.list(); session.getTransaction().commit(); System.out.println(questions.size()); for (Question question : questions) { for(Answer answer : question.getAnswers()){ System.out.println(answer.getAnswer()); } } } }
HibernateUtil.java
package lan.study.hibernate.util; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { return new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }