使用hibernate注解和配置oracle的序列,出现序列不断自增的问题

先说明见一下:总共有两个表,一个是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,总是差那么一拍。

4个回答

去掉SEQUENCE的触发器,Hibernate是直接调用SEQUENCE.nextval的,此时如果数据库端有主键触发器的话就会增加2

你没有贴你的表结构, 是否你的表是自增的?

如果是, 应该去掉.

  1. 请阅读cascade的文档,检查相关设置,查看后台的log输出
  2. 这种模型不建议用many-to-many,实际开发中,建议建立中间实体,用2个one-to-many来模拟many-to-many

首先,关联表肯定是两个外键拉起来的,否则数据库不整个都乱了。保存报错只能说明你映射文件配置有问题。中间关联表中居然出现主表没有的id,肯定是hibernate映射那边出了问题。JPA的注解我不是很了解,如果是.hbm.xml文件就能帮你了。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐