-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Relation Simple dans une SubClass,violation de clé étrang
PostPosted: Thu Dec 22, 2005 1:22 pm 
Beginner
Beginner

Joined: Mon Aug 08, 2005 7:54 am
Posts: 27
Bonjour à tous,

Voilà mon problème en deux mot : Une subclasse qui a une dépendance simple par une clé étrangère vers une autre classe ne génère une erreur quand je cherche à sauvegarder une instance de cette classe (J'espère que ce descriptif bref n'est pas trop obscur).

Alors voilà mon mapping :
Code:
        <class name="AbstractIdentityCard" abstract="true">
                <id name="id" column="ID_CARD">
                        <generator class="increment"/>
                </id>                               
                <property name="state" column="STATE" type="int" not-null="true"/>
                <property name="creationDate" column="CREATION_DATE" type="date"/>
                <!-- Mapping the Domain -->
                <joined-subclass name="Domain" table="DOMAIN" >
                        <key column="ID_DOMAIN"/>
                        <many-to-one    name="properties"
                                        class="com.ao.o3s.data.Element"
                                        column="ID_PROPERTIES"
                                        cascade="all"
                                        unique="true"                                       
                                        foreign-key="FK3_PROPERTY_ID">
                        </many-to-one>
                </joined-subclass>
</class>


et le message d'erreur associé :
Quote:

[TestORM] - "Starting HibSession"
[TestORM] - "Beginning Transaction"
Hibernate: select max(ID_CARD) from AbstractIdentityCard
[TestORM] - "Transaction commit"
Hibernate: insert into AbstractIdentityCard (STATE, CREATION_DATE, ID_CARD) values (?, ?, ?)
Hibernate: insert into DOMAIN (ID_PROPERTIES, ID_DOMAIN) values (?, ?)
[org.hibernate.util.JDBCExceptionReporter] - "SQL Error: 0, SQLState: 23503"
[org.hibernate.util.JDBCExceptionReporter] - "ERREUR: Une instruction insert ou update sur la table «domain» viole la contrainte de clé étrangère «fk3_property_id»"
[org.hibernate.event.def.AbstractFlushingEventListener] - "Could not synchronize database state with session"
org.hibernate.exception.ConstraintViolationException: could not insert: [com.ao.o3s.sheets.Domain]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:69)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2077)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2426)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)


En observant bien au debugger l'execution , je suis arrivé au constat suivant : Hibernate n'ajoute pas la dépendance ( ici une instance de com.ao.o3s.Element) avant de stocker ma 'subclass' en tant que telle. Du coup, quand il veut insérer un nouvel élément Domain , on une violiation de clé étrangère, car la dépendance n'a pas encore réçu son "id'.

En hibernate2, je pense que la solution aurait été un inverse=true, mais je ne trouve pas d'équivalent en Hib3 ( ce qui ne signifie pas que je regrette la suppression de ce mot-clé : ) attention ! )... J'ai essayé différentes approches mais je n'arrive pas à dire à hibernate : "stock la dépendance avant" ! N'est-ce pas le rôle de cascade ? Ou alors ce problème est le symptôme d'un problème autres dans mon mapping, mais alors lequel ?

Merci d'avance pour toute participation ou remarque. Je suis un peu à cours de piste don c même si vous ne pensez pas avoir la solution, une question ou remarque peut m'aider merci !

_________________
Belaran,
"Slowly climbing the moutain of Hibernate's mystery..."


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 26, 2005 10:19 am 
Beginner
Beginner

Joined: Mon Aug 08, 2005 7:54 am
Posts: 27
Hum... Je ne suis pas sûr que mon exposé ci dessus expose bien mon problème. Comme il y bcp de classes et de la récursivité, j'ai fais un diagramme de classe qui je le pense résume pas trop mal la situation :

Image

Voilà le mapping de Element :

Code:
<!-- Mapping for Element -->
        <class name="Element" table="LINE">
                <id name="id" column="ID_LINE">
                        <generator class="increment"/>
                </id>               
                 
                <property name="Rank" column="RANK" type="long" not-null="true"/>
                <property name="Value" column="VALUE" type="string"/>
                <property name="Comment" column="COMMENT" type="string"/>
                <!-- <property name="meta" column="META"/> -->       
               
                <!-- Mapping to RefLabel -->
                <many-to-one       name="RefLabel"
                                   column="LABEL_ID"
                                   class="RefLabel"
                                   not-null="false"
                                   unique="true"
                                   not-found="ignore"
                                   foreign-key="FK2_LABEL_ID">
                </many-to-one>                   
                <!-- Mapping to the parent -->
                <many-to-one        name="container"
                                    class="Element"
                                    access="property"
                                    unique="true"
                                    cascade="save-update, persist,merge"
                                    foreign-key="FK1_CONTAINER_ID">
                        <column name="CONTAINER_ID" not-null="false" />
                </many-to-one>               
                <!-- Mapping to the children -->
                <set    name="elements"
                        access="property"
                        sort="comparator"
                        cascade="all"
                        inverse="true"
                        order-by="LABEL_ID asc">
                        <key column="CONTAINER_ID"/>
                        <one-to-many class="Element"/>
                </set>
        </class>


Qui est assez complexe finalement non ?

Et dans le premier post, on trouve le mapping de Domain...

A priori, la partie class+subclass fonctionne très bien dès que je retire le many-to_one vers Element. Le mapping de Element fonctionne très bien aussi, mais je commence à le soupçonner de ne pas être assez précis et donc d'être incohérent avec le modèle exposé ci dessus.

Ca fait près de deux semaines que je consacre régulièrement du temps à ce problème et je suis un peu à bout de piste...

_________________
Belaran,
"Slowly climbing the moutain of Hibernate's mystery..."


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 27, 2005 1:27 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Tu es *sûr*?
Réduit le case le plus possible. Tu devrais trouver l'erreur, sinon poste le sur JIRA, mais il doit être minimal et fonctionner directe (sans dependance)

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 27, 2005 1:46 pm 
Beginner
Beginner

Joined: Mon Aug 08, 2005 7:54 am
Posts: 27
Dans mon test case, j'ai essayé de réduire au minimum.
Au plus basique , la situation est la suivante :
    1 Element a une dépendance envers un object appelé RefLabel. Ceci est mappé et se passe sans problème ( donc je ne l'ai pas mentionné ci dessous)
    2 Domain est dépendant envers sa classe abstraire mère, cela aussi se passe sans problème.
    3 Domain est dépendant envers un Element, qui peut lui même avoir des dépendances vers d'autres Element. C'est au niveau de cette relation que j'ai des problèmes.


J'ai un test Unitaire qui se contente de créer la base et de la remplir. Au moment, où il veut ajouter la première instance de Domain : il y a une violation de clé étrangère envers l'Element. Dans les traces, on voit bien que Hib3 n'a pas stocké l'instance d'Element avant d'essayer de stocker l'instance de Domain...

Est ce que je suis "sûr" de cela ? Non, bien sûr, je suis encore très "léger" en Hibernate ( même si le livre de Anthony m'aide bien, merci :) ). Le problème est peut être ailleurs. Je soupçonne mon mapping de ne pas être correcte ( c quand même souvent plus ça que Hib3 qui est à la source des problèmes). Je ne crois pas être tombé sur un bug JIRAsable, le problème est trop près des fonctionnalitées élémentaires de Hibernate...

Je vais essayer de faire une application encore plus atomatique ( peut être juste faire un mapping entre une joined-class très simple et une relation 1-1 simple, puis transformer la dépendance en dépendance récursive comme dans mon cas).

En tout cas, merci d'avoir au moins lu mon problème, je sais déjà au moins que la solution n'est pas une simple étourderie ou une misconception sur le fonctionnement d'hibernate, sinon je pense qu'elle t'aurais sauté au yeux...

_________________
Belaran,
"Slowly climbing the moutain of Hibernate's mystery..."


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 28, 2005 5:23 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
soit bient sûr de mettre cascade="all" ou "persist,save-update" sur le lien entre domain et element.

Autre point Element bizarre:
- tu as une many-to-one unique=true, ce qui veut dire que c'est fonctionnellement une one to one. Or tu a définis une collection de l'autre côté (elle n'aura qu'un seul element)

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 28, 2005 11:23 am 
Beginner
Beginner

Joined: Mon Aug 08, 2005 7:54 am
Posts: 27
Effectivement fonctionnellement, c'est une one-to-one vers le premier élément d'un arbre. Le problème vient bien des cascades. En fait, j'ai réalisé une mini app à part qui reprend le même schema et qui marche sans problème. Cela m'a permis d'isoler le problème qui se trouve à un autre niveau de mon modèle. En effet, Element a une dépendance vers un objet intitulé RefLabel, avec le mapping suivant :

Code:
<many-to-one       name="RefLabel"
                                   column="LABEL_ID"
                                   class="RefLabel"
                                   not-null="false"
                                   cascade="all"
                                   unique="true"
                                   not-found="ignore"
                                   foreign-key="FK2_LABEL_ID"/>


C'est cette dépendance qui me pose un problème.

Tout cela marche très bien, sauf que plusieurs instance d'Element peuvent avoir une dépendance vers la même instance de RefLabel et du coup :

Quote:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.ao.o3s.data.Element#0]


J'avais enlevé le cascade, et alors l'erreur s'est reportée plus loin. Par contre, je ne vois pas comment configurer Hib3 pour gérer ce problème... : (

Comme j'ai réussi à recréer le problème dans une 'standalone app', je la met à dispo ici. Recréer le projet devrait prendre deux click dans Eclipse, et sinon, il est assez aisé de lancer le test Unitaire... ( juste ne pas oublier de mettre le répertoire lib dans le classpath...). Hibernate est configuré pour Postgres, mais changer pr une autre db est très simple.

_________________
Belaran,
"Slowly climbing the moutain of Hibernate's mystery..."


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 02, 2006 11:48 am 
Beginner
Beginner

Joined: Mon Aug 08, 2005 7:54 am
Posts: 27
La réponse à mon problème sera la source d'une nouvelle humiliation publique pour ma personne mais bon...

Le problème était dans les données que j'injecte avec identifier égale à 0L plutot que null... Donc, dès le second appel à une méthode pour sauvegarder un object, hib3 retrouvé une instance associé à 0 plutot qu'à null...

_________________
Belaran,
"Slowly climbing the moutain of Hibernate's mystery..."


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.