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)
public Set<Answer> getAnswers() {
return answers;
}
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;
}
}