[Spring/Hibernate] RollBack sur plusieurs ajouts
Bonjour,
Je me suis mis à Spring et Hibernate il y a quelques jours pour rendre l'application sur laquelle je travaille plus "pro".
J'ai donc commencé à mettre en place une couche d'accès aux données avec des services simples pour les tester. Mes premiers essais sont concluants néanmoins je n'arrive pas à mettre un rollback en place pour une fonction d'ajout. Je tente d'ajouter deux objets dans mon DAO et de faire planter le deuxième pour vérifier que le premier est bien rollbacké. Mais ce n'est pas le cas.
Tout d'abord mes config spring sont les suivantes :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<bean id="myTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="transactionProxy" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="myTransactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
</props>
</property>
</bean>
<bean id="noeudDao" class="dao.hibernate3.NoeudDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="noeudManagerTarget" class="service.impl.NoeudManagerImpl">
<property name="noeudDao">
<ref bean="noeudDao" />
</property>
</bean>
<bean id="noeudManager" parent="transactionProxy">
<property name="transactionManager">
<ref bean="myTransactionManager"/>
</property>
<property name="target">
<ref bean="noeudManagerTarget"/>
</property>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
</property>
</bean>
</beans> |
noeudDao est mon interface DAO implémenté par la classe NoeudDaoImpl :
noeudDao
Code:
1 2 3 4
|
public interface NoeudDao {
public boolean Ajout(String type, Hashtable tableValeurs);
} |
noeudDaoImpl
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public class NoeudDaoImpl extends HibernateDaoSupport implements NoeudDao {
public boolean Ajout(String type, Hashtable tableValeurs) throws DataAccessException{
if (null == type || null == tableValeurs) {
throw new IllegalArgumentException("type and tableValeurs are mandatory. Null values are forbidden.");
}
logger.info("Accès à l'objet de type : "+type);
Noeud noeud = new Noeud();
noeud.setEtat("0");
noeud.setIdnoeud("080808080808");
noeud.setNumnoeudpere("0102030405");
Noeud noeud1 = new Noeud();
getHibernateTemplate().saveOrUpdate(noeud);
getHibernateTemplate().saveOrUpdate(noeud1);
return true;
}
} |
On peut voir dans ma fonction Ajout() que je créé deux objets Noeud, le premier est correct, le deuxième n'a pas d'idnoeud et donc provoque une exception DataAccessException sur la fonction saveorupdate().
Code:
1 2
|
2007-10-31 09:58:00 ERROR [UserManagerImpl] Exception - DataAccessException occurs : ids for this class must be manually assigned before calling save(): donnees.Noeud; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): donnees.Noeud on complete Ajout(). |
Néanmoins le premier Noeud est tout de même comité.
Voici le code de mon service qui appelle ce DAO.
NoeudManager (interface du service)
Code:
1 2 3 4 5 6
|
@Transactional (readOnly=false, propagation=Propagation.REQUIRED)
public interface NoeudManager {
public boolean Ajout(String type, Hashtable tableValeurs);
} |
Implémentation NoeudManagerImpl
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
public class NoeudManagerImpl implements NoeudManager {
private final Log logger = LogFactory.getLog(UserManagerImpl.class);
private NoeudDao noeudDao = null;
public void setObjectDao(NoeudDao objectDao){
this.noeudDao = objectDao;
}
public boolean Ajout(String type, Hashtable tableValeurs) {
try{
return noeudDao.Ajout(type, tableValeurs);
}
catch(DataAccessException e) {
// Critical errors : database unreachable, etc.
logger.error("Exception - DataAccessException occurs : "+e.getMessage()
+" on complete Ajout().");
return false;
}
}
} |
D'après ce que j'ai compris de mes lectures, la DataAccessException devrait provoquer le rollback de la session en cours.
Mais j'ai surement pas compris un truc.
J'espère avoir été clair.
Merci d'avance pour votre aide.