J'ai un problème pour essayer de mapper un arbre d'héritage. Une version simplifiée de mon modèle est comme ceci:Problème de l'arbre d'héritage persistant
@MappedSuperclass
@Embeddable
public class BaseEmbedded implements Serializable {
@Column(name="BE_FIELD")
private String beField;
// Getters and setters follow
}
@MappedSuperclass
@Embeddable
public class DerivedEmbedded extends BaseEmbedded {
@Column(name="DE_FIELD")
private String deField;
// Getters and setters follow
}
@MappedSuperclass
public abstract class BaseClass implements Serializable {
@Embedded
protected BaseEmbedded embedded;
public BaseClass() {
this.embedded = new BaseEmbedded();
}
// Getters and setters follow
}
@Entity
@Table(name="MYTABLE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING)
public class DerivedClass extends BaseClass {
@Id
@Column(name="ID", nullable=false)
private Long id;
@Column(name="TYPE", nullable=false, insertable=false, updatable=false)
private String type;
public DerivedClass() {
this.embedded = new DerivedClass();
}
// Getters and setters follow
}
@Entity
@DiscriminatorValue("A")
public class DerivedClassA extends DerivedClass {
@Embeddable
public static NestedClassA extends DerivedEmbedded {
@Column(name="FIELD_CLASS_A")
private String fieldClassA;
}
public DerivedClassA() {
this.embedded = new NestedClassA();
}
// Getters and setters follow
}
@Entity
@DiscriminatorValue("B")
public class DerivedClassB extends DerivedClass {
@Embeddable
public static NestedClassB extends DerivedEmbedded {
@Column(name="FIELD_CLASS_B")
private String fieldClassB;
}
public DerivedClassB() {
this.embedded = new NestedClassB();
}
// Getters and setters follow
}
Au niveau Java, ce modèle fonctionne bien, et je crois est celui qui convient. Mon problème arrive quand il est temps de persister un objet. Au moment de l'exécution, je peux créer un objet qui pourrait être une instance de DerivedClass, DerivedClassA ou DerivedClassB. Comme vous pouvez le voir, chacune des classes dérivées introduit un nouveau champ qui n'a de sens que pour cette classe dérivée spécifique. Toutes les classes partagent la même table physique dans la base de données. Si je persiste un objet de type DerivedClass, j'attends que les champs BE_FIELD, DE_FIELD, ID et TYPE soient conservés avec leurs valeurs et que les champs restants soient NULL. Si je persiste un objet de type DerivedClass A, je m'attends à ce que ces mêmes champs et le champ FIELD_CLASS_A soient conservés avec leurs valeurs et que le champ FIELD_CLASS_B soit nul. Quelque chose d'équivalent pour un objet de type DerivedClassB.
Étant donné que l'annotation @Embedded
se trouve uniquement dans BaseClass, Hibernate ne conserve les champs que jusqu'à ce niveau dans l'arborescence. Je ne sais pas comment dire à Hibernate que je veux persister jusqu'au niveau approprié dans l'arbre, en fonction du type réel de la propriété incorporée.
Je ne peux pas avoir une autre propriété @Embedded
dans les sous-classes car cela dupliquerait les données déjà présentes dans la superclasse et briserait également le modèle Java.
Je ne peux pas non plus déclarer que la propriété incorporée est d'un type plus spécifique, puisque c'est seulement à l'exécution quand l'objet réel est créé et que je n'ai pas une seule branche dans la hiérarchie.
Est-il possible de résoudre mon problème? Ou devrais-je me résigner à accepter qu'il n'y a aucun moyen de maintenir le modèle Java tel quel?
Toute aide sera grandement appréciée.
aide par mes réponse à tout? – Gray