Salut,
Je suis un newbie Hibernate, et je viens de remarquer un comportement surprenant lors de la sauvegarde d'un objet Java. En effet, j'ai une association one-to-many entre deux tables A et B, et quand je supprime un élément de B, sa foreign-key est mise à null par Hibernate au lieu de supprimer l'élément.
J'utilise Hibernate 3.2 et une DB Sybase
Voici un peu de code pour décrire le problème.
ListeAlerte.hbm.xml
Code:
<hibernate-mapping package="fr.rssalert.liste">
<class name="ListeAlerte" table="AL_LISTEALERTES">
<id name="id" type="long">
<column name="P_CLISTEALERTE" sql-type="numeric(7,0)"/>
<generator class="native"/>
</id>
<property name="description" type="string">
<column name="D_LDESCRIPTION"/>
</property>
...
<list name="listeCriteres" cascade="all-delete-orphan" lazy="false">
<key column="C_CLISTEALERTE"/>
<index column="D_CRITEREIDX"/>
<one-to-many class="fr.rssalert.liste.Critere"/>
</list>
</class>
</hibernate-mapping>
Critere.hbm.xmlCode:
<hibernate-mapping package="fr.rssalert.liste">
<class name="Critere" table="AL_CRITERES">
<id name="id" type="long">
<column name="P_CCRITERE" sql-type="numeric(7,0)"/>
<generator class="native"/>
</id>
<property name="donnee" type="string">
<column name="D_DONNEE"/>
</property>
...
<property name="index" type="int">
<column name="D_CRITEREIDX"/>
</property>
</class>
</hibernate-mapping>
Je charge un objet ListeAlerte avec sa liste de Critere de la manière suivante
Code:
public ListeAlerte findById(final Long id) {
final List l = sessionFactory.getCurrentSession().createCriteria(
ListeAlerte.class).add(Restrictions.idEq(id))
.setResultTransformer(
CriteriaSpecification.DISTINCT_ROOT_ENTITY).list();
if (l.size() != 0) {
return (ListeAlerte) l.get(0);
} else {
return null;
}
}
L'objet ListeAlerte est accessible et modifiable par l'utilisateur dans une page HTML et il peut ensuite le sauvegarder:
Code:
public void save(final ListeAlerte listeAlerte) {
sessionFactory.getCurrentSession().saveOrUpdate(listeAlerte);
}
Ca fonctionne, les modificatins de ListeAlerte et ses Critere sont bien sauvegardés, mais, si un Critere a été supprimé de ListeAlerte, sa foreign-key C_CLISTEALERTE, et l'index de la liste D_CRITEREIDX sont mis à null alors que je préfèrerai que la ligne soit complètement supprimée de la table.
Les logs de Hibernate
Quote:
Hibernate: update AL_LISTEALERTES set C_CAPPLIEMET=?, D_LDESCRIPTION=?, C_CTYPE=?, C_CNIVEAU=? where P_CLISTEALERTE=?
Hibernate: update AL_CRITERES set D_DONNEE=?, D_CTYPE=?, C_CCOMP=?, D_VALEUR=?, D_CRITEREIDX=? where P_CCRITERE=?
Hibernate: update AL_CRITERES set D_DONNEE=?, D_CTYPE=?, C_CCOMP=?, D_VALEUR=?, D_CRITEREIDX=? where P_CCRITERE=?
Hibernate: update AL_CRITERES set C_CLISTEALERTE=null, D_CRITEREIDX=null where C_CLISTEALERTE=?
Hibernate: update AL_CRITERES set C_CLISTEALERTE=?, D_CRITEREIDX=? where P_CCRITERE=?
Hibernate: update AL_CRITERES set C_CLISTEALERTE=?, D_CRITEREIDX=? where P_CCRITERE=?
Je pensais que
cascade="all-delete-orphan" suffirait pour supprimer la ligne, mais à priori, c'est pas suffisant.
Maintenant, je manque d'idées.... :(
Laurent