1. 程式人生 > >Hibernate 多對多 中間表含有其他欄位 註解方式實現

Hibernate 多對多 中間表含有其他欄位 註解方式實現

需求:

兩個實體類:Teacher.class Student.class 中間表包含了一個額外欄位:score

Teacher.calss

id name
1 Mr.zhang
2 Mr.wang

Student.class

id name
1 Xiaoming
2 Xiaohong

中間表

id teacher_id student_id score
1 1 1 89
2 1 2 90

解決辦法:

按照傳統的多對多註解實現,中間表是以自身id為預設主鍵,另外包含了兩個實體類的id,共3個欄位,不能新增額外的欄位。

解決辦法是將ManyToMany 分解成兩個OneToMany。

解決過程:

顯示看到了這個blog:http://blog.csdn.net/liuxianbing119/article/details/7283769 知道這麼處理,但是可以新增成功,刪除一直不成功。

後來翻到了wiki裡面的介紹:http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany

知道這種方法肯定沒錯,就又試了幾次,終於成功了。

程式碼:

1. AbstractEntity.java

package com.cc.persistence;

import java.io.Serializable;

public abstract class AbstractEntity implements Persistable {
	public abstract Serializable getInternalId();
	
	@Override
	public boolean equals(Object o) {
		if (o == null) return false;
		if (!o.getClass().getName().equals(this.getClass().getName())) return false;
		return ((Persistable)o).getInternalId().equals(this.getInternalId());
	}
	
	@Override
	public int hashCode() {
		return this.getInternalId().hashCode();
	}
}

2.Teacher.java
package com.xx;

import java.io.Serializable;
import java.util.Date;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "teacher")
public class Teacher extends AbstractEntity{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 2392788383432498751L;

	private Long id;
	private String 	name;

	
	private Set<TeacherStudent> teacherStudents;
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}
	
	@Column(name = "name", length = 256)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
	@OneToMany(mappedBy = "teacher")
	public Set<NoticeGroup> getTeacherStudents() {
		return teacherStudents;
	}

	public void setTeacherStudents(Set<TeacherStudent> teacherStudents) {
		this.teacherStudents = teacherStudents;
	}

	@Override
	@Transient
	public Serializable getInternalId() {
		return id;
	}
	
}

3.Student.java
package com.xx;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "student")
public class Student extends AbstractEntity {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6380182108640048430L;

	private Long 	id;
	private String 	name;
	
	private Set<TeacherStudent> teacherStudents;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column(length = 256)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@OneToMany(mappedBy = "student")
	public Set<TeacherStudent> TeacherStudents() {
		return teacherStudents;
	}

	public void setTeacherStudents(Set<TeacherStudent> teacherStudents) {
		this.teacherStudents = teacherStudents;
	}

	@Override
	@Transient
	public Serializable getInternalId() {
		return id;
	}

}

4.TeacherStudent.java
package com.xx;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "teacher_student")
public class TeacherStudent extends AbstractEntity {	

	/**
	 * 
	 */
	private static final long serialVersionUID = 4876371202187846251L;
	private Long 	id;
	private Teacher 	teacher;
	private Student 	student;
	private Integer score; 
	
	@Id
	@Column(name = "id", nullable = false)
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	
	@ManyToOne
	@JoinColumn(name = "teacher_id")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	
	@ManyToOne
	@JoinColumn(name = "student_id")
	public Student getStudent() {
		return student;
	}
	public void setStudent(Student student) {
		this.student = student;
	}
	
	@Column(name="score")
	public Integer getScore() {
		return score;
	}
	public void setScore(Integer score) {
		this.score = score;
	}
	
	@Override
	@Transient
	public Serializable getInternalId() {
		// TODO Auto-generated method stub
		return id;
	}
	
	
}

5.TeacherDaoImpl.java

   新增一個teacher-student 關係:

	@Override
	public boolean addStudentScore(Long teacherId,Long studentId,Integer score) {
		// TODO Auto-generated method stub	
		Student student = (Student) studentDao.findById(studentId);
		Session session = this.getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Teacher teacher = (Teacher) session.get(
					getEntityClass(), teacherId);
			if (teacher != null && student != null) {
				//new TeacherStudent
				TeacherStudent ts = new TeacherStudent();	
				ts.setTeacher(teacher);
				ts.setStudent(student);			
				ts.setScore(score);			
				session.save(ts);
				session.flush();
				tx.commit();
				return true;
			}

		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
		} finally {
			session.close();
		}
		return false;
	}

刪除一個teacher-student 關係:

	@Override
	public boolean removeStudentScore(Long teacherId,Long studentId) {
		// TODO Auto-generated method stub
		Student student = (Student) studentDao.findById(studentId);
		Session session = this.getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Teacher teacher = (Teacher) session.get(
					getEntityClass(), teacherId);
			Set<TeacherStudent> teacherStudents = null;
			if (teacher != null && student != null) {
				teacherStudents = teacher.getTeacherStudents();
				if (teacherStudents.size()>0){
					for(TeacherStudent teacherStudent:teacherStudents){
						if(teacherStudent.getStudent().getId().equals(studentId) && teacherStudent.getTeacher().getId().equals(teacherId)){
							session.delete(teacherStudent);
						}
					}
				}
				session.flush();
				tx.commit();
				return true;
			}

		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
		} finally {
			session.close();
		}
		return false;
	}