Skip to content

Instantly share code, notes, and snippets.

@limjinsun
Last active September 3, 2018 21:51
Show Gist options
  • Select an option

  • Save limjinsun/b3e55f3c3f84c0a8ecabf93b67315b56 to your computer and use it in GitHub Desktop.

Select an option

Save limjinsun/b3e55f3c3f84c0a8ecabf93b67315b56 to your computer and use it in GitHub Desktop.

하이버네트 many to many 릴레이션 셋업

Many to Many 릴레이션 셋업은 필수적으로 중간의 조인테이블이 필요하다.

SET foreign_key_checks=0;

CREATE TABLE `course_student` (
  `course_id` int(11) NOT NULL,
  `student_id` int(11) NOT NULL,
  
  PRIMARY KEY (`course_id`,`student_id`),
  
  KEY `FK_STUDENT_idx` (`student_id`),
  
  CONSTRAINT `FK_COURSE_05` FOREIGN KEY (`course_id`) 
  REFERENCES `course` (`id`) 
  ON DELETE NO ACTION ON UPDATE NO ACTION,
  
  CONSTRAINT `FK_STUDENT` FOREIGN KEY (`student_id`) 
  REFERENCES `student` (`id`) 
  ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

각 칼럼에 포린키를 설정하여 다른 테이블 (course/student) 의 id 컬럼을 레퍼런스 하도록 만들어 준다. 이 말은, 각각 course / student 는 여러개의 해당 오브젝트를 갖는다는 의미.

그래서 entity 클래스에 list 형태로 객체를 만들어 준다.

public class Course {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id")
	private int id;
	
	@Column(name="title")
	private String title;
	
	@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH})
	@JoinColumn(name="instructor_id")
	private Instructor instructor;
	
	/* 리스트로 선언해줌. */
	private List<Student> students;
	
  
	/* constructor and getter and setter */
	public Course() {
		// empty constructor
	}
  // 생략
  
}
public class Student {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id")
	private int id;

	@Column(name="first_name")
	private String firstName;

	@Column(name="last_name")
	private String lastName;

	@Column(name="email")
	private String email;
	
  
  	/* 리스트로 선언해줌. */
	private List<Course> courses;
	
	/* constructor and getter and setter */
	public Student() {
		//empty constructor
	}
  
  //생략
  

그 다음은 겟터와 셋터를 만들어 주고 해야할일이, 어노테이션을 이용해 관계를 만들어 주는 것이다.

@ManyToMany(cascade= {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH})
@JoinTable(name="course_student", joinColumns=@JoinColumn(name="student_id"), inverseJoinColumns=@JoinColumn(name="course_id"))

ManyToMany 릴레이션을 만들어 주고, cascadeType 에서 Delete 는 빼준다. 테이블을 조인시켜줘야 하는데.

@JoinTable(name="<조인되는 테이블 이름>", joinColumns=@JoinColumn(name="<조인되는 컬럼>"), inverseJoinColumns=@JoinColumn(name="<연결돠는 컬럼>"))

이렇게 만들어 지고, 그래서 전체적으로 보면,

@ManyToMany(cascade= {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH})
@JoinTable(name="course_student", joinColumns=@JoinColumn(name="student_id"), inverseJoinColumns=@JoinColumn(name="course_id"))
private List<Course> courses;
	
	/* 생략 */
	
@ManyToMany(cascade= {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH})
@JoinTable(name="course_student", joinColumns=@JoinColumn(name="course_id"), inverseJoinColumns=@JoinColumn(name="student_id"))
private List<Student> students;

이런 형태로 클래스 안에 넣어지게 된다.

자료의 삽입

Many to Many relation 에서 주의 할 점은, 이 릴레이션을 가질려고 하는 두 엔트리 모두 데이터 베이스 안에 미리 있어야 한다는 점이다.

public class ManyToManyCreate {

	private static SessionFactory sessionFactory;

	public ManyToManyCreate () {
		// empty constructor. 
	} 

	public static SessionFactory getFactory () {

		if(sessionFactory == null) {
			try {
				sessionFactory = new Configuration().configure().buildSessionFactory();
			}
			catch (Exception e) {e.printStackTrace();}
		}
		return sessionFactory;
	}

	public static void main(String[] args) {

		Session session = getFactory().openSession();
		Transaction transaction = null;
		
		Course skateCourse = new Course("Skate");
		Course hockeyCourse = new Course("Hockey");
		
		List<Course> tempCourseList = new ArrayList<Course>();
		tempCourseList.add(skateCourse);
		tempCourseList.add(hockeyCourse);
		
		Student student1 = new Student("Jin", "Lim", "jin@luv2code.com");
		
		student1.setCourses(tempCourseList);
		
		try {
			transaction = session.beginTransaction();
			
			session.save(skateCourse);
			session.save(hockeyCourse);
			
			session.save(student1);

			transaction.commit();
		} catch (Exception e) { 
			if (transaction!=null) {
				transaction.rollback(); 
			} 
			e.printStackTrace(); 
		} finally { 
			session.close();
		}

	}
	
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment