Bonjour,
Je rencontre un petit soucis avec Hibernate dans le cadre de la sauvegarde d'un graph d'objet. Pas bien grave puisque tout est sauvegardé comme il faut sans violation des contraintes mais j'ai deux requête qui ne me semble pas nécessaire.
Un membre (class Member) a une adresse (class Address).
Une adresse (class Address) à un et un seul un pays (class Country).
Un membre a un set (java.util.Set) de qualifications (class Qualification)
Une qualification (class Qualification) est rattachée à un et un seul diplôme (class Degree)
Toutes les foreign keys entre les tables T_MEMBER, T_DEGREE, T_ADDRESS, T_COUNTRY et T_QUALIFICATION sont activées en base, les valeurs nulles sont interdites pour les colonnes correspondantes aux foreign keys.
Dans une classe de test je créé un nouveau membre (appelons le member), auquel j'affecte une nouvelle adresse (à qui j'affecte un pays existant) et deux nouvelles qualifications (à chacune d'elle j'affecte un diplôme existant).
Une fois que le graph d'objet 'member' correspond à ce que je veux sauvegarder je fais un session.save sur 'member'.
Tout se passe bien (les requêtes sont exécutés dans le bon ordre et les contraintes ne sont pas violées) mais Hibernate semble exécuter deux requêtes qui ne me paraissent pas nécessaires : voir les deux derniers updates dans la trace.
Hibernate version:
3.03
Mapping documents:
Extrait du mapping de la classe Member :
<many-to-one
name="address"
class="fr.as.poc.model.impl.Address"
cascade="all"
column="ID_ADDRESS"
not-null="true"
unique="true"
/>
<set name="qualifications" cascade="all">
<key column="ID_MEMBER" not-null="true"/>
<one-to-many class="fr.as.poc.model.impl.Qualification"/>
</set>
Extrait du mapping de la classe Address :
<many-to-one
name="country"
class="fr.as.poc.model.impl.Country"
cascade="none"
outer-join="true"
column="ID_COUNTRY"
not-null="true"
lazy="false"
/>
Extrait du mapping de la classe Qualification :
<many-to-one
name="degree"
class="fr.as.poc.model.impl.Degree"
cascade="none"
outer-join="auto"
column="ID_DEGREE"
not-null="true"
/>
Name and version of the database you are using:
JDBC driver: Oracle JDBC driver, version: 9.2.0.1.0
The generated SQL (show_sql=true):
15:06:21,827 | DEBUG | SQL:311 | select degree0_.ID_DEGREE as ID1_0_, degree0_.NAME as NAME2_0_ from T_DEGREE degree0_ where degree0_.ID_DEGREE=?
15:06:22,337 | DEBUG | SQL:311 | select degree0_.ID_DEGREE as ID1_0_, degree0_.NAME as NAME2_0_ from T_DEGREE degree0_ where degree0_.ID_DEGREE=?
15:06:22,748 | DEBUG | SQL:311 | select country0_.ID_COUNTRY as ID1_0_, country0_.NAME as NAME1_0_ from T_COUNTRY country0_ where country0_.ID_COUNTRY=?
15:06:23,269 | DEBUG | SQL:311 | select seq_id_member.nextval from dual
15:06:23,569 | DEBUG | SQL:311 | select seq_id_address.nextval from dual
15:06:23,779 | DEBUG | SQL:311 | select country_.ID_COUNTRY, country_.NAME as NAME1_ from T_COUNTRY country_ where country_.ID_COUNTRY=?
15:06:23,930 | DEBUG | SQL:311 | select seq_id_qualification.nextval from dual
15:06:24,080 | DEBUG | SQL:311 | select seq_id_qualification.nextval from dual
15:06:24,240 | DEBUG | SQL:311 | insert into T_ADDRESS (ADDRESS_1, ADDRESS_2, ADDRESS_3, ADDRESS_4, ZIPCODE, CITY, ID_COUNTRY, EMAIL, FAX_NUMBER, PHONE_NUMBER, ID_ADDRESS) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
15:06:24,320 | DEBUG | SQL:311 | insert into T_MEMBER (FIRSTNAME, LASTNAME, ID_ADDRESS, ID_MEMBER) values (?, ?, ?, ?)
15:06:24,390 | DEBUG | SQL:311 | insert into T_QUALIFICATION (ID_DEGREE, YEAR, ID_MEMBER, ID_QUALIFICATION) values (?, ?, ?, ?)
15:06:24,430 | DEBUG | SQL:311 | insert into T_QUALIFICATION (ID_DEGREE, YEAR, ID_MEMBER, ID_QUALIFICATION) values (?, ?, ?, ?)
15:06:24,480 | DEBUG | SQL:311 | update T_QUALIFICATION set ID_MEMBER=? where ID_QUALIFICATION=?
15:06:24,500 | DEBUG | SQL:311 | update T_QUALIFICATION set ID_MEMBER=? where ID_QUALIFICATION=?
Debug level Hibernate log excerpt:
AbstractCollectionPersister:474 | Static SQL for collection: fr.as.poc.model.impl.Member.qualifications
AbstractCollectionPersister:475 | Row insert: update T_QUALIFICATION set ID_MEMBER=? where ID_QUALIFICATION=?
AbstractCollectionPersister:477 | Row delete: update T_QUALIFICATION set ID_MEMBER=null where ID_MEMBER=? and ID_QUALIFICATION=?
Je ne comprends pas la raison d'être des deux derniers update. Pourquoi attribuer un ID_MEMBER aux deux lignes de la table T_QUALIFICATION alors que l'ID a déjà été attribué lors des INSERT ? Si j'avais rempli mon set avec 50 qualifications j'aurais eu 50 updates.
Et les je ne comprends pas les deux dernières lignes du log. Un 'row delete' se traduirait par une requête SQL UPDATE alors que lorsque j'appelle session.delete(member) c'est bien un DELETE qui est exécuté. Quant au 'row insert', il se matérialise bien par une requête UPDATE, c'est bien le problème.
Je n'ai pas encore trouvé de réponse sur la doc/faq/forum,
Merci pour votre aide.
A+
|