2010-09-30 11 views
32

Comment configurer les annotations dans l'exemple de code suivant? Je voudrais coller uniquement avec les annotations JPA et éviter les dépendances spécifiques à Hibernate. Le code ci-dessous est-il correct?Classe abstraite héritée avec JPA (+ Hibernate)

@Entity 
public class RefExample extends RefData { 

} 

(Il y aura plusieurs versions de ces classes, RefSomeOtherExample, etc, et une table db par classe. Certains peuvent ajouter des champs supplémentaires (colonnes), mais la plupart seront tout simplement utiliser des champs de base hérités de la "RefData" classe de base)

classe de base.

@Entity 
public abstract class RefData { 

    private long id; 
    private String code; 
    private String desc; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(unique = true, nullable = false) 
    public long getId() { 

     return id; 
    } 

    public void setId(long id) { 

     this.id = id; 
    } 

    @Column(unique = true, nullable = false, length=8) 
    public String getCode() { 

     return code; 
    } 

    public void setCode(String code) { 

     this.code = code; 
    } 

    @Column(unique = true, nullable = false, length=80) 
    public String getDesc() { 

     return desc; 
    } 

    public void setDesc(String desc) { 

     this.desc = desc; 
    } 
} 

en fin de compte, j'aimerais générer des scripts de création de schémas de cette classe en utilisant la SchemaExport de mise en veille prolongée. Dans le cas ci-dessus, ces deux classes ne devraient aboutir qu'à la création d'une seule table nommée "RefExample" avec les trois colonnes de "RefData". Est-ce que ça va marcher?

Répondre

75

De JPA 1.0:

Les deux classes abstraites et concrètes peuvent être des entités. Les classes abstraites et concrètes peuvent être annotées avec l'annotation d'entité, mappées en tant qu'entités et interrogées en tant qu'entités.

Les entités peuvent étendre des classes non-entité et les classes non-entité peuvent étendre les classes d'entité.

Comme vous voulez une seule table, vous devez utiliser l'héritage Single Table.

suffit de définir une colonne discriminante comme suit:

@Entity 
@DiscriminatorColumn(name="REF_TYPE") 
public abstract class RefData { 

Mais si vous ne voulez pas compter sur les stratégies d'héritage JPA, vous pouvez utiliser MappedSuperclass à la place:

@MappedSuperclass 
public abstract class RefData { 

spécification JPA

Une entité peut hériter d'une super-classe qui fournit des informations d'état et de mappage d'entité persistantes, mais w Il n'est pas lui-même une entité. En règle générale, l'objet d'une telle superclasse mappée consiste à définir des informations d'état et de mappage communes à plusieurs classes d'entités.

Gardez à l'esprit vous ne pouvez pas utiliser @Entity et @MappedSuperclass en même temps.

+0

@Crusader Voir ici: http://stackoverflow.com/questions/2700680/table-per-subclass-inheritance-relationship-how-to-query-against-the-parent-clas/3017146#3017146 comment je contourne les problèmes de performance lorsqu'il s'agit de l'héritage. ** Si vous souhaitez utiliser la stratégie TABLE PAR CLASS, la base de données cible doit prendre en charge la stratégie de génération d'identité **. –

+1

Pas encore sûr à 100% mais je pense que MappedSuperclass peut être ma meilleure option. Toutes ces tables sont vraiment pour est de stocker les valeurs présentées dans les champs déroulants qui sont affectés (un à plusieurs) aux enregistrements de données réelles. – Manius

+0

Il est possible d'interroger (HQL ou JPQL) sur les propriétés présentes dans la superclasse annotée avec @MappedSuperclass – Sunil

0

Vous pouvez utiliser l'une des stratégies d'héritage pour cela. Votre cas semble être le cas de la classe unique pour la hiérarchie.

Vérifier this

+1

Cet article m'a étonné. J'imaginais en fait la Table par stratégie de classe concrète décrite ici (une table par classe "RefExample" concrète), mais elle dit que l'approche est "pas populaire" ET optionnelle dans JPA. Aucune des trois options ne semble correspondre exactement à mes exigences. Les rats! – Manius

5

@MappedSuperClass est travaillé pour moi. J'avais du mal à mapper une vue à 2 objets qui sont des classes parents et enfants. Ma vue est jointe à partir de 2 tables. Les clés primaires des deux tables sont présentes dans la vue.@DiscriminatorColumn ne fonctionne pas pour moi car il nécessite une colonne exclusivement attribuée au type de données de l'objet et il lance 'repeated Column in object exception' que je n'ai pas pu résoudre.

J'ai lu ce forum et j'ai essayé @MappedSuperClass annotation. Ça fait l'affaire.

J'ai mis @MappedSuperclass à la superclasse et mettre les @Id et @GeneratedValue dans l'identifiant superclasse. Dans la sous-classe que j'ai donné comme

@Entity 
@Table(name="view_name") 

et utilisé l'objet sous-classe pour récupérer les données de la vue. C'est tout.

Héritage des annotations d'hibernation pour la table jointe avec out utilisant @DiscriminatorColumn a travaillé pour moi.

Merci.