首页 > 代码库 > Hibernate 多对多 中间表含有其他字段 注解方式实现

Hibernate 多对多 中间表含有其他字段 注解方式实现

需求:

两个实体类:Teacher.class Student.class 中间表包含了一个额外字段:score


Teacher.calss

idname
1Mr.zhang
2Mr.wang

Student.class

idname
1Xiaoming
2Xiaohong

中间表

idteacher_idstudent_idscore
11189
21290

解决办法:

按照传统的多对多注解实现,中间表是以自身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;
	}



Hibernate 多对多 中间表含有其他字段 注解方式实现