先说明见一下:总共有两个表,一个是teacher,另一个是student,多对多关系,都分别有序列S_Teacher和S_Student,使用oracle9i数据库,hibernate3.3,spring2.5和JPA的注解
下面是我的源代码:
Teacher model
[code="java"]
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name = "Teacher")
public class Teacher implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="S_Teacher")
@SequenceGenerator(name="S_Teacher",allocationSize=1,initialValue=1, sequenceName="S_Teacher")
private Long tid;
private String tname;
private Integer tage;
private Date tcreateDate;
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY, mappedBy = "teachers", targetEntity = Student.class)
private List<Student> students=new ArrayList<Student>();
public Long getTid() {
return tid;
}
public void setTid(Long tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public Integer getTage() {
return tage;
}
public void setTage(Integer tage) {
this.tage = tage;
}
public Date getTcreateDate() {
return tcreateDate;
}
public void setTcreateDate(Date tcreateDate) {
this.tcreateDate = tcreateDate;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
[/code]
Student model
[code="java"]
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
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.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name = "Student")
public class Student implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="S_Student")
@SequenceGenerator(name="S_Student", allocationSize=1, initialValue=1,sequenceName="S_Student")
private Long sid;
private String sname;
private Integer sage;
private Date screateDate;
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY, targetEntity = Teacher.class)
@JoinTable(name = "RS_Teacher_Student", joinColumns = { @JoinColumn(name = "sid")}, inverseJoinColumns = { @JoinColumn(name = "tid") })
private List<Teacher> teachers=new ArrayList<Teacher>();
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getSage() {
return sage;
}
public void setSage(Integer sage) {
this.sage = sage;
}
public Date getScreateDate() {
return screateDate;
}
public void setScreateDate(Date screateDate) {
this.screateDate = screateDate;
}
public List<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(List<Teacher> teachers) {
this.teachers = teachers;
}
}
[/code]
TeacherDAO
[code="java"]
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class TeacherDAO extends HibernateDaoSupport {
public void insertTeacher(Teacher t){
getHibernateTemplate().saveOrUpdate(t);
}
}
[/code]
StudentDAO
[code="java"]
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class StudentDAO extends HibernateDaoSupport {
public void insertStudent(Student s){
getHibernateTemplate().saveOrUpdate(s);
}
}
[/code]
测试程序
[code="java"]
import java.util.Date;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestOracle {
private ApplicationContext context;
private TeacherDAO tdao;
private StudentDAO sdao;
public TestOracle() {
context = new ClassPathXmlApplicationContext(
new String[] { "application_oracle.xml" });
tdao=(TeacherDAO)context.getBean("TeacherDAO");
sdao=(StudentDAO)context.getBean("StudentDAO");
}
public void save(){
Teacher t=new Teacher();
t.setTname("baiyj");
t.setTage(Integer.valueOf("23"));
t.setTcreateDate(new Date());
Student s1=new Student();
s1.setSname("t11");
s1.setSage(Integer.valueOf("21"));
s1.setScreateDate(new Date());
Student s2=new Student();
s2.setSname("t12");
s2.setSage(Integer.valueOf("22"));
s2.setScreateDate(new Date());
s1.getTeachers().add(t);
s2.getTeachers().add(t);
tdao.insertTeacher(t);
sdao.insertStudent(s1);
sdao.insertStudent(s2);
}
/**
* @param args
*/
public static void main(String[] args) {
TestOracle to=new TestOracle();
to.save();
}
}
[/code]
spring配置文件application_oracle.xml
[code="xml"]
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
value="oracle.jdbc.driver.OracleDriver" />
value="jdbc:oracle:thin:@127.0.0.1:1521:TEST" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.test.oracle.Teacher</value>
<value>com.test.oracle.Student</value>
</list>
</property>
</bean>
<!--Hibernate TransactionManager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="TeacherDAO" class="com.test.oracle.TeacherDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="StudentDAO" class="com.test.oracle.StudentDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
[/code]
现在的问题就是:执行完TestOracle后,数据库中可以保存成功,但是student和teacher表里面的主键id都和他们之间的关联表里的id分别都对应不上,比如student里面有两条记录,他们id分别是2,4;teacher表里面也有id为2的记录,但是在他们的关系表中却成了teacher是1,student是1,3了,请问是那里配置的不对吗?另外关系表里面没有强制设置外键关联,原来设置了外键关联,但保存报错,说是“违反完整约束条件,未找到父项关键字”,现在去掉关联,但出现上面这种情况,主键id总是“错位”,真不知道是怎么回事。
[b]问题补充:[/b]
我用的是序列啊,是自增的。怎么序列不能自增吗?
[b]问题补充:[/b]
我将教师对学生的关系改成一对多的关联关系,结果也是一样的,比如:teacher表里面的主键id是4,而student表里面的tid都是3,总是差那么一拍。