初学JPA, 多对多问题。
例子很简单,老师-学生关系映射。
持久化是org.hibernate.ejb.HibernatePersistence。
被维护端是老师表,维护端是学生表,取消级联操作。
老师:
public class TTeacher {
@Id @GeneratedValue
private Integer id;
@Column(length=10,nullable=false)
private String name;
@ManyToMany(cascade={CascadeType.REFRESH},mappedBy="Ts")
private Set<SStudent> Ss=new HashSet<SStudent>();
public TTeacher() {
super();
}
public TTeacher(String name) {
super();
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<SStudent> getSs() {
return Ss;
}
public void setSs(Set<SStudent> ss) {
Ss = ss;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
public class SStudent {
@Id @GeneratedValue
private Integer id;
@Column(length=10,nullable=false)
private String name;
//inverseJoinColumns被维护段外键
@ManyToMany(cascade={CascadeType.REFRESH})@JoinTable(name="teacher_student",inverseJoinColumns
=@JoinColumn(name="teacher_id"),joinColumns=@JoinColumn(name="student_id"))
private Set<TTeacher> Ts=new HashSet<TTeacher>();
public SStudent() {
super();
}
public SStudent(String name) {
super();
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TTeacher> getTs() {
return Ts;
}
public void setTs(Set<TTeacher> ts) {
Ts = ts;
}
public void addTeacher(TTeacher t){
this.Ts.add(t);
}
public void removeTeacher(TTeacher t){
if(this.Ts.contains(t))
this.Ts.remove(t);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SStudent other = (SStudent) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Test
public void save() {
factory=Persistence.createEntityManagerFactory("test");
entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
TTeacher tc1=new TTeacher("王老师");
TTeacher tc2=new TTeacher("钱老师");
SStudent st1=new SStudent("张同学");
SStudent st2=new SStudent("赵同学");
/*
entityManager.persist(tc1);
entityManager.persist(tc2);
entityManager.persist(st1);
entityManager.persist(st2);
st1.addTeacher(tc1);
st1.addTeacher(tc2);
st2.addTeacher(tc1);
st2.addTeacher(tc2);
插入正确,无异常
*/
st1.addTeacher(tc1);
st1.addTeacher(tc2);
st2.addTeacher(tc1);
st2.addTeacher(tc2);
entityManager.persist(tc1);
entityManager.persist(tc2);
entityManager.persist(st1);
entityManager.persist(st2);
//无异常,但插入不正确,即teacher_student表少插了关于第二个老师的2个记录
entityManager.getTransaction().commit();
entityManager.close();
factory.close();
}