Hibernate:行被另一个事务更新或删除(或未保存的值映射不正确)

时间:2013-05-22 16:36:00

标签: java hibernate dao hibernate-mapping

首先抱歉。我知道它有很多相同的主题,但也许我的英语不好或者我找不到合适的答案。

我使用乐观锁定@Version注释。我需要一个表中的一行来自一个表有来自不同表的众多行,我确实插入了这样:

所以它看起来像这样:

  

机构(这是我表(机构)的一行)

       - CreationDate A (this is row from different table(CreationDate) bind with Institution with JoinTable, ManyToMany)

       - CreationDate B (this is row from different table(CreationDate) bind with Institution with JoinTable, ManyToMany)

       - CreationDate C (this is row from different table(CreationDate) bind with Institution with JoinTable, ManyToMany)

因此,为了使这个CreationDate具有不同的变化,我决定手动为我想要添加我的CreationDate的特定机构添加id。

我的主要方法类:

CreationDate crdate = new CreationDate();   
Institution inst= new Institution();
Set<Institution> instituset = new HashSet<Institution>();

***inst.setInstitutionId(2);***

inst.setNameOfInstitution("MyInstitution");
inst.setTypeName("Education");
instituset.add(inst);

当我想要在我的机构中添加另一行数据首先在数据库中将我的版本行更改为一个后,我的代码中添加了星号标记的行。

这是我的机构实体:

@Entity
@Table(name="INSTITUTION")
public class Institution implements Serializable{


    private static final long serialVersionUID = -7636394097858726922L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="INSTITUTION_ID")
    private int institutionId;


    @Version
    @Column(name="VERSION")
    private int version;


    @Column(name="NAME_INSTITUTION")
    private String nameOfInstitution;

    @Column(name="TYPE_NAME")
    private String typeName;


    @ManyToMany(mappedBy="institution", fetch = FetchType.LAZY)
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    private Set<CreationDate> creationDate = new HashSet<CreationDate>();

    //getter and setter methods ommited

    public String toString() {
        return institutionId + " , " + nameOfInstitution + " , " + typeName 
    }       
}

我的CreatioDate实体:

@Entity
@Table(name="CREATION_DATE")
public class CreationDate implements Serializable {


    private static final long serialVersionUID = 1648102358397071136L;

    @Id
    @GeneratedValue(strategy=IDENTITY)
    @Column(name="DATE_ID")
    private int dateId;


    @Column(name="PARTICULAR_DATE")
    private Date particularDate;

    @Version
    @Column(name="VERSION")
    private int version;

    @Temporal(TemporalType.DATE)
    @Column(name="CHILD_GO_SCHOOL_DATE")
    private Date childGoSchoolDate;

    @Temporal(TemporalType.DATE)
    @Column(name="CHILD_ADMISSION_DATE")
    private Date childAdmissionDate;


    @ManyToMany(fetch = FetchType.LAZY)
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    @JoinTable(name="CREATIONDATE_INSTITUTION", 
                                    joinColumns=@JoinColumn(name="DATE_ID"), 
                    inverseJoinColumns=@JoinColumn(name="INSTITUTION_ID"))
    private Set<Institution> institution = new HashSet<Institution>();

    @OneToMany(fetch=FetchType.EAGER, orphanRemoval=true)
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    @JoinTable(name="SRC_DATE", joinColumns=@JoinColumn(name="DATE_ID"),
                    inverseJoinColumns=@JoinColumn(name="SRC_ID"))
    private List<ScheduleRotationChild> scheduleRotationChild = new ArrayList<ScheduleRotationChild>();


        //getter and setter methods ommited


    public String toString() {

        return  dateId + " , " 
            + particularDate + " , " 
            + childGoSchoolDate + " , " 
            + childAdmissionDate + "  " + scheduleRotationChild ;

    }
}

我的道:

public CreationDate insertData(CreationDate creationdate) {
        sessionFactory.getCurrentSession().saveOrUpdate(creationdate);
        log.info(creationdate.getDateId());
        return creationdate;

    }

因此,当我尝试将我的数据插入到我的机构的secont时间时发生异常。

 Hibernate: insert into CREATION_DATE (CHILD_ADMISSION_DATE,
 CHILD_GO_SCHOOL_DATE, PARTICULAR_DATE, VERSION) values (?, ?, ?, ?)

 Hibernate: insert into SCHEDULE_ROTATION_CHILD (CHILD_ADMITTED,
 CHILD_GO_SCHOOL, CHILD_UNDER_3_YEARSOLD, CHILD_UPPER_3_YEARSOLD,
 DAY_SCHEDULE, NUMBER_OF_CHILD, ROTATION, VERSION, WORK_SCHEDULE)
 values (?, ?, ?, ?, ?, ?, ?, ?, ?)

 Hibernate: update INSTITUTION set
 NAME_INSTITUTION=?, TYPE_NAME=?, VERSION=? where INSTITUTION_ID=? and
 VERSION=? Exception in thread "main"

org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException:
     Object of class [edu.demidov.dom.Institution] with identifier [2]:
     optimistic locking failed; nested exception is
     org.hibernate.StaleObjectStateException: Row was updated or deleted by
    another transaction (or unsaved-value mapping was incorrect):
     [edu.demidov.dom.Institution#2]

4 个答案:

答案 0 :(得分:12)

我面临同样的问题,它是spring和hibernate的结合。在打破我的头3-4个小时后,我只是随机检查了与版本相关的专栏。当我使用旧表时,我最近引入了版本列,并且没有默认为零 - 所以它为所有行添加了null以及我试图删除的行。所以就像猜测我输入0,神奇地它在下一次运行时起作用。我希望有所帮助。

答案 1 :(得分:2)

如果我理解正确,您正在尝试将ID为2的现有机构添加到新的CreationDate中。由于机构已存在,因此您不应创建新机构。你应该从Hibernate Session中获取它:

Institution institution = (Institution) session.load(Institution.class, 2);
creationDate.addInstitution(institution);

答案 2 :(得分:0)

检查要更新的模型对象。 基本上,您应该检查“ Not null”值; 例如已经定义的主键等。这将有所帮助。

答案 3 :(得分:0)

对我来说,问题是我总是使用相关 saveJpaRepository 方法,而没有先获取现有实体。因此,第一次保存总是很顺利,但是当我更新实体时,抛出了异常。我检查了数据库中的 version 列,发现版本永远不会超过 1。确保在更新之前始终尝试获取实体!