关于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;
    }

}

相关推荐