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 :

"mappedBy" et héritage


Sujet :

JPA Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    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
    Par défaut "mappedBy" et héritage
    Bonjour,

    Je cherche à modéliser une classe de relation générique entre 2 objets. En "naviguant" sur la classe générique, j'obtiendrai ainsi toutes les relations liées à un objet. Pour des soucis de verbosité, je ne fais apparaitre qu'un côté de la relation.

    J'ai donc défini une entité abstraite Link:
    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
    @Entity
    public abstract class Link extends Persistable {
     
    //	protected Persistable roleA;
    	protected Persistable roleB;
     
    	@ManyToOne
    	public Persistable getRoleB() {
    		return roleB;
    	}
     
    	public void setRoleB(Persistable roleB) {
    		this.roleB = roleB;
    	}
    }
    La classe Persistable est une classe générique pour toutes mes entités; elle contient les champs id et version, ainsi que la stratégie d'héritage (TABLE_PER_CLASS)
    Maintenant, je définis 2 classes de lien:
    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
    @Entity
    public class L1 extends Link {
     
    	@Transient
    	public Q getQ()
    	{
    		return (Q)roleB;
    	}
     
    	public L1()
    	{
    	}
     
    	public L1(Q q)
    	{
    		setRoleB(q);
    		q.getL1().add(this);
    	}
    }
    et
    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
    @Entity
    public class L2 extends Link {
     
    	@Transient
    	public R getR()
    	{
    		return (R)roleB;
    	}
     
    	public L2()
    	{
    	}
     
    	public L2(R r)
    	{
    		setRoleB(r);
    		r.getL2().add(this);
    	}
    }
    avec R et Q définis comme suit:
    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
    @Entity
    public class Q extends Persistable {
     
    	private List<L1> l1;
     
    	@OneToMany(fetch=FetchType.LAZY, mappedBy="roleB")
    	public List<L1> getL1() {
    		if (l1 == null)
    		{
    			l1 = new ArrayList<L1>();
    		}
    		return l1;
    	}
    	public void setL1(List<L1> l1) {
    		this.l1 = l1;
    	}
     
    	public Q()
    	{
    	}
    }
     
    @Entity
    public class R extends Persistable {
     
    	private List<L2> l2;
     
    	@OneToMany(fetch=FetchType.LAZY, mappedBy="roleB")
    	public List<L2> getL2() {
    		if (l2 == null)
    		{
    			l2 = new ArrayList<L2>();
    		}
    		return l2;
    	}
    	public void setL2(List<L2> l2) {
    		this.l2 = l2;
    	}
     
    	public R()
    	{
    	}
    }
    J'instancie maintenant tous mes objets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    		Q q = new Q();
    		em.persist(q);
     
    		R r = new R();
    		em.persist(r);
     
    		L1 l1 = new L1(q);
    		em.persist(l1);
     
    		L2 l2 = new L2(r);
    		em.persist(l2);
    et j'obtiens l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: test.model.L2.roleB in test.model.R.l2
    Ce qui peut éventuellement se comprendre.
    J'ai donc essayé de remplacer les L1 et L2 sur les classes R et Q par Link. Mais je tombe alors sur l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`monprojet/l1`, CONSTRAINT `FK9802000848F126b1` FOREIGN KEY (`roleB_id`) REFERENCES `r` (`id`))
    Effectivement, une foreign key a été crée pour toutes les sous classes de Link, à la fois vers Q et vers R.

    Est-il possible, soit de faire un "mappedBy" vers un attribut hérité (solution au premier problème), ou bien de configurer en détail la génération des foreign key pour éviter le deuxième problème ?

    Merci d'avance

  2. #2
    Membre averti
    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
    Par défaut
    Bonsoir,
    J'ai finalement trouvé la réponse: je ne dois/peux pas définir l1 et l2 sur les classes Q et R, mais sur Persistable. Puisque j'ai défini roleB comme Persistable sur Link.

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