[hibernate-issues] [Hibernate-JIRA] Created: (HHH-2796) Generated version are incremented by Hibernate

Heba Tawfik (JIRA) noreply at atlassian.com
Sat Aug 18 07:27:13 EDT 2007


Generated version are incremented by Hibernate
----------------------------------------------

                 Key: HHH-2796
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2796
             Project: Hibernate3
          Issue Type: Bug
          Components: core
    Affects Versions: 3.2.1
         Environment: 3.2.1, Oracle 10g
            Reporter: Heba Tawfik


Creating a new entity which it's version is set to generated="always" & saving it, then in the same session adding an object to any of its on-to-many relationships is throwing a StaleObjectStateException.
To regenerate the problem, consider the following code
1- departement.hbm.xml :
----------------------------------------
<hibernate-mapping package="com.myproject.domain">
<class name="Departement" table="Departement">
<id name="id">
   <column name="dept_id" />
</id>
<version column="version" generated="always" name="version" type="integer" unsaved-value="null" />
<property name="name" column="name" />
<bag name="employees" inverse="true" cascade="all" lazy="true">
  <key column="dept_id"></key>
   <one-to-many class="Employee" />
</bag>
</class>
</hibernate-mapping>

2- employee.hbm.xml :
--------------------------------------
<hibernate-mapping package="com.myproject.domain">
<class name="Employee" table="Employee">
 <id name="id">
    <column name="employee_id" />
</id>
<property name="firstName" column="first_name" />
<property name="lastName" column="last_name" />
<property name="age" column="age" />
<property name="salary" column="salary" />
<many-to-one cascade="none"
	class="com.myproject.domain.Departement"
	column="dept_id" embed-xml="true" insert="false"
	name="department" not-null="false" 
	unique="false" update="false" not-found="ignore">
</many-to-one>	
</class>
</hibernate-mapping>

3- Departement.Java
---------------------------
package com.myproject.domain;

import java.util.ArrayList;
import java.util.List;

public class Departement extends BaseDepartement{

	int id;
	String name;
	List employees;
	Integer version;

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public Integer getVersion() {
		return version;
	}
	public void setVersion(Integer version) {
		this.version = version;
	}

	public List getEmployees() {
		return employees;
	}

	public void setEmployees(List employees) {
		this.employees = employees;
	}
	
	public void addToEmployeeList(Employee emp)
	{
		if(employees==null)
		{
			setEmployees(new ArrayList());
		}
		employees.add(emp);
	}
}

4- Employee.Java :
---------------------------
package com.myproject.domain;

public class Employee {
	
	int id;
	String firstName;
	String lastName;
	int age;
	int salary;
	BaseDepartement department;
	
	public BaseDepartement getDepartment() {
		return department;
	}
	public void setDepartment(BaseDepartement department) {
		this.department = department;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public int getSalary() {
		return salary;
	}
	public void setSalary(int salary) {
		this.salary = salary;
	}
}

4- Code To Test :
------------------------
public static void main(String args[]) throws Exception
{
SessionFactory factory = new Configuration().configure("com/myproject/config/hibernate.cfg.xml").buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
Departement aDept =new Departement();
aDept.setId(10);
aDept.setName("Test");
session.save(aDept);
transaction.commit();
transaction = session.beginTransaction();
Employee emp=new Employee();
emp.setId(10);
emp.setFirstName("test");
emp.setLastName("test");
emp.setSalary(10);
emp.setAge(10);
emp.setDepartment(aDept);
aDept.addToEmployeeList(emp);
session.saveOrUpdate(aDept);
transaction.commit();
session.close();
}

On the database, the default value for version cloumn is set to "1" and a trigger is defined as follow on the Departement table:
create or replace
TRIGGER TRIGGER1
 BEFORE UPDATE ON DEPARTEMENT 
FOR EACH ROW 
BEGIN
 :new.version:= :old.version + 1;
END;


Upon executing the above code, the following is the hibernate logging :
automatically flushing session

    /* insert com.eds.myproject.domain.Departement
        */ insert 
        into
            Departement
            (name, dept_id) 
        values
            (?, ?)
binding 'Test' to parameter: 1
binding '10' to parameter: 2

    /* get generated state com.eds.myproject.domain.Departement */ select
        departemen_.version as version1_ 
    from
        Departement departemen_ 
    where
        departemen_.dept_id=?
binding '10' to parameter: 1
returning '1' as column: version1_
before transaction completion
after transaction completion
automatically flushing session

    /* get current state com.eds.myproject.domain.Employee */ select
        employee_.employee_id,
        employee_.first_name as first2_0_,
        employee_.last_name as last3_0_,
        employee_.age as age0_,
        employee_.salary as salary0_ 
    from
        Employee employee_ 
    where
        employee_.employee_id=?
binding '10' to parameter: 1

    /* insert com.eds.myproject.domain.Employee
        */ insert 
        into
            Employee
            (first_name, last_name, age, salary, employee_id) 
        values
            (?, ?, ?, ?, ?)
binding 'test' to parameter: 1
binding 'test' to parameter: 2
binding '10' to parameter: 3
binding '10' to parameter: 4
binding '10' to parameter: 5

    /* update
        com.eds.myproject.domain.Departement */ update
            Departement 
        set
            name=? 
        where
            dept_id=? 
            and version=?
binding 'Test' to parameter: 1
binding '10' to parameter: 2
binding '2' to parameter: 3
Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.eds.myproject.domain.Departement#10]
	at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1714)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2357)
	at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2257)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2557)
	at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
	at com.eds.myproject.test.Test.main(Test.java:43)
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.eds.myproject.domain.Departement#10]
	at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1714)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2357)
	at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2257)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2557)
	at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
	at com.eds.myproject.test.Test.main(Test.java:43)

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list