需求:
两个实体类: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();
}
}
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;
}
}
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;
}
}
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;
}
}添加一个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 多对多 中间表含有其他字段 注解方式实现
原文地址:http://blog.csdn.net/geeklei/article/details/43218189