Problem Description
****************
During a transaction that rollbacks, all NEW OBJECTs that had been persisted in it, mantain the Key that has been assigned to then by the GENERATOR. So, the next time i try to saveOrUpdate thats NEW OBJECTs, Hibernate manages its as if they where PERSISTED OBJECTS, generating a new exception.
Ambient Details
************
Application
-------------
Spring (release 1.0.2)
Hibernate (2.1.0)
Java (jdk 1.4.1_02-b06)
Application Configuration
-----------------------------
* transactionManager: org.springframework.orm.hibernate.HibernateTransac tionManager
* transactionInterceptor: org.springframework.transaction.interceptor.Transa ctionInterceptor
* hibernate.dialect: net.sf.hibernate.dialect.PostgreSQLDialect
* GENERATOR: "sequence"
DB
----
postgreSQL 7.4.3
Linux Red Hat 9
Analisys Realized and More Details
****************************
Analisys Realized
---------------------
1) PersonService.savePerson(IPerson person) is invoked by a client
2) PersonDAO.savePerson(IPerson person) is then invoked by PersonService.savePerson(IPerson person)
3) Before the inserts in the DB, the session uses GENERATOR to generate the unique Key (eg: 1421) that identifies the person.
4) Suppose that, while inserting in the DB, a constrain is violated and an error is raise. The transactionManager inits the rollback process and finish it successfully.
5) Unfortunately, after that process, the person mantains a relation to that generated Key (1421), but it does not exists in the DB after the rollback.
6) So, the next time i try to saveOrUpdate that person, Hibernate manages its as if it where an already PERSISTED person, generating, calling the Session.doUpdate( ... ) method, generating an Hibernate exception.
database
-----------
create table person
(
id serial,
firstname varchar(20),
lastname varchar(20),
sex varchar(1) not null
);
person.hbm
--------------
<class name="Person" table="person">
<id column="id" name="id" type="java.lang.Long">
<generator class="sequence">
<param name="sequence">elector_id_seq</param>
</generator>
</id>
<property column="apellido" name="fistname" not-null="false" type="string" />
<property column="apellido" name="lastname" not-null="false" type="string" />
<property column="sex" name="lastname" not-null="true" type="string" />
</class>
conf_hibernate.xml
-----------------------
<bean id="transactionManager" class="org.springframework.orm.hibernate.Hibernate TransactionManager">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor .TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">
<value>test.Interfaces.IPersonService.save*=PROPAG ATION_REQUIRED,-DataAccessException</value>
</property>
</bean>
<bean id="person" class="test.BO.Person">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>
<bean id="personDao" class="test.logica.PersonDAO">
<property name="sessionFactory">
<ref local="mySessionFactory"/>
</property>
</bean>
<bean id="personServiceTarget" class="test.BO.PersonService">
<property name="personDao">
<ref bean="personDao"/>
</property>
</bean>
<bean id="personService" class="org.springframework.aop.framework.ProxyFact oryBean">
<property name="proxyInterfaces">
<value>test.Interfaces.IPersonService</value>
</property>
<property name="interceptorNames">
<value>transactionInterceptor,personServiceTarge t</value>
</property>
</bean>
class
-------
PersonService class contains a savePerson(IPerson) methods that is intercepted for transactional reasons:
public void savePerson(IPerson person) throws DataAccessException {
this.personDao.savePerson(person);
}
PersonDAO class contains the next method:
public void savePerson(IPerson person) throws DataAccessException {
Session session = SessionFactoryUtils.getSession(getSessionFactory() , false);
try{
session.saveOrUpdate(person);
}
catch (...){
...
}
}


Reply With Quote