IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JPA Java Discussion :

Pb de query avec héritage


Sujet :

JPA Java

  1. #1
    Membre à l'essai
    Profil pro
    chef
    Inscrit en
    Septembre 2005
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : chef

    Informations forums :
    Inscription : Septembre 2005
    Messages : 13
    Points : 12
    Points
    12
    Par défaut Pb de query avec héritage
    Bonjour,
    Voici mon problème:
    J'ai 3 entités: une classe mère BasicEntity et 2 sous classes Entity1 et Entity2, qui ont des propriétés communes, déléguées sur une "embedded entity" EmbeddableInfo
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    @Entity
    @Inheritance(strategy=InheritanceType.JOINED)
    public class BasicEntity {
    	Long id;
     
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	public Long getId() {
    		return id;
    	}
    ...
     
    @Entity
    public class Entity1 extends BasicEntity {
     
    	String prop1;
     
    	EmbeddableInfo embeddedInfo;
     
    	@Embedded
    	public EmbeddableInfo getEmbeddedInfo() {
    		return embeddedInfo;
    	}
    ...
     
    @Entity
    public class Entity2 extends BasicEntity {
     
    	String prop2;
     
    	EmbeddableInfo embeddedInfo;
     
    	@Embedded
    	public EmbeddableInfo getEmbeddedInfo() {
    		return embeddedInfo;
    	}
    ...
     
    et
    @Embeddable
    public class EmbeddableInfo {
     
    	String infoProp;
    ...
    Lorsque je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<BasicEntity> result0 = em.createQuery("Select e from BasicEntity e").getResultList();
    je récupère bien toutes les instances de Entity1 et Entity2

    Par contre, lorsque je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<BasicEntity> result1 = em.createQuery("Select e from BasicEntity e where (e.embeddedInfo.infoProp = 'eki')").getResultList();
    je ne récupère que les instances de Entity1 (la requête générée ne permet pas de remonter les instances de Entity2)

    Y a-t-il une explication ou s'agit-il d'un bug Hibernate ?

    Précision: je ne souhaite pas déplacer EmbeddableInfo sur BasicEntity car je voudrai pouvoir combiner définir plusieurs "EmbeddableInfo" et ensuite les combiner au besoin sur mes objets métiers (un peu du multi-héritage)

    Merci d'avance

  2. #2
    Membre à l'essai
    Profil pro
    chef
    Inscrit en
    Septembre 2005
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : chef

    Informations forums :
    Inscription : Septembre 2005
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    En changeant la politique d'héritage et la méthode de génération des Ids comme celà:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Entity
    @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
    abstract public class BasicEntity {
     
    	Long id;
     
    	@Id
    	@GeneratedValue(strategy = GenerationType.TABLE)
    	public Long getId() {
    		return id;
    	}
    ça fonctionne correctement, mais je ne sais pas trop pourquoi.

    Y a-t-il une explication ou s'agit-il d'un bug Hibernate ?

  3. #3
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par rdeman Voir le message
    Y a-t-il une explication ou s'agit-il d'un bug Hibernate ?
    oui à la première et non à la seconde, le problème est bien que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    EmbeddableInfo embeddedInfo;
    est un champ défini 2 fois…

    il faut le mettre dans une classe ancêtre de Entity1 et Entity2, si vous ne voulez pas que ce soit BasicEntity alors il faut que ce soit une classe intermédiaire supplémentaire…

  4. #4
    Membre à l'essai
    Profil pro
    chef
    Inscrit en
    Septembre 2005
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : chef

    Informations forums :
    Inscription : Septembre 2005
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Merci pour cette réponse,

    En fait, je ne souhaite pas regrouper les EmbeddableInfo sur une seule et unique classe abstraite, BasicEntity ou autre. En effet, je souhaite mettre en place une approche générique que je peux essayer d'expliquer rapidement.

    Pour un comportement donné (exemple, "lockable"), je créé une interface java (Lockable) et une "embedded entity" associée (LockInfo):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public interface Lockable()
    {
    	public LockInfo  getLockInfo()
    	public setLockInfo(LockInfo lockInfo)
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    @Embeddable
    public class LockInfo {
     
    	boolean locked;
    ...
    A côté de celà, j'ai un service (LockService) qui contient toutes les méthodes pour manipuler un Lockable. Ces methodes sont les seules à accéder aux attributs de LockInfo.

    Ensuite, pour modéliser mes objets métiers , je doit effectuer 2 opérations:
    - ajouter un champ LockInfo
    - implémenter Lockable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	private LockInfo lockInfo;
     
    	@Embedded
    	public LockInfo getLockInfo() {
    		return lockInfo;
    	}
     
    	public void setLockInfo(LockInfo lockInfo) {
    		this.lockInfo= lockInfo;
    	}
    Et bien sûr, je peux combiner plusieurs comportements basiques sur un même objet métier (lockable, foldered, versionned, ...). C'est pour celà que je disais que c'est un peu du multi-héritage.

    Pour en revenir à mes moutons et à JPA, lorsque j'exécute la requête :
    "Select e from BasicEntity e where (e.embeddedInfo.infoProp = 'eki')"
    je n'ai aucune erreur. Celà semble signifier que JPA est capable de gérer ce genre de situation (une clause where sur des attributs qui ne sont pas directement sur la classe requêtée, mais potentiellement sur des sous-classes).
    De plus, en utilisant une stratégie "TABLE_PER_CLASS", le résultat est bien celui attendu.
    Mais pourquoi le n'est-il pas en utilisant une stratégie JOINED ?

    Merci d'avance

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par rdeman Voir le message
    Mais pourquoi le n'est-il pas en utilisant une stratégie JOINED ?

    Merci d'avance
    il serait intéressant d'activer la visualisation du SQL
    <property name="hibernate.show_sql" value="true"/>
    pour y voir plus clair…

    mais a priori (vu le changement de comportement lié à la stratégie) c'est un problème lié au JOIN…

  6. #6
    Membre à l'essai
    Profil pro
    chef
    Inscrit en
    Septembre 2005
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : chef

    Informations forums :
    Inscription : Septembre 2005
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Voici ce que la trace SQL renvoie avec une stratégie JOINED:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    select basicentit0_.id as id0_,
    basicentit0_.prop as prop0_,
    basicentit0_1_.infoProp as infoProp1_,
    basicentit0_1_.prop1 as prop2_1_,
    basicentit0_2_.infoProp as infoProp3_,
    basicentit0_2_.prop2 as prop2_3_,
    case when basicentit0_1_.id is not null then 1
         when basicentit0_2_.id is not null then 2
         when basicentit0_.id is not null then 0
    end as clazz_
    from BasicEntity basicentit0_
    left outer join Entity1 basicentit0_1_ on basicentit0_.id=basicentit0_1_.id
    left outer join Entity2 basicentit0_2_ on basicentit0_.id=basicentit0_2_.id
    where basicentit0_1_.infoProp='eki'
    et avec TABLE_PER_CLASS:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select basicentit0_.id as id0_,
    basicentit0_.prop as prop0_,
    basicentit0_.infoProp as infoProp1_,
    basicentit0_.prop1 as prop2_1_,
    basicentit0_.infoProp as infoProp3_,
    basicentit0_.prop2 as prop2_3_,
    basicentit0_.clazz_ as clazz_
    from ( select prop1, prop, null as prop2, infoProp, id, 1 as clazz_ from Entity1
     union select null as prop1, prop, prop2, infoProp, id, 2 as clazz_ from Entity2 ) basicentit0_
     where basicentit0_.infoProp='eki'

Discussions similaires

  1. Objet Query avec un héritage multiple
    Par QAYS dans le forum Langage
    Réponses: 5
    Dernier message: 01/11/2007, 10h18
  2. Query avec un CREATE TEMPORARY TABLE = erreur ?
    Par d3mone dans le forum Bases de données
    Réponses: 2
    Dernier message: 16/05/2007, 19h11
  3. Erreur du designer avec héritage d'une classe abstraite
    Par Xzander dans le forum Windows Forms
    Réponses: 4
    Dernier message: 04/04/2007, 00h36
  4. [Visual Web] Query avec deux paramètres
    Par eponette dans le forum NetBeans
    Réponses: 1
    Dernier message: 19/03/2007, 13h44
  5. optimisation query avec BETWEEN
    Par maxtin dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 13/01/2007, 01h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo