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:
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:
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
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:
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:
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:
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:
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
Partager