web-dev-qa-db-fra.com

Classe abstraite héritée avec JPA (+ Hibernate)

Comment configureriez-vous les annotations dans l'exemple de code suivant? J'aimerais rester avec les annotations JPA uniquement et éviter les dépendances spécifiques à Hibernate. Le code ci-dessous est-il correct?

@Entity
public class RefExample extends RefData {

}

(Il y aura plusieurs versions de ces classes, RefSomeOtherExample, etc., et une table de base de données par classe. Certaines personnes peuvent ajouter des champs supplémentaires (colonnes), mais la plupart utilisent simplement les champs de base hérités de la classe de base "RefData".)

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éma à l'aide de la classe SchemaExport d'Hibernate. 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?

37
Manius

A partir de la spécification JPA 1.0:

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

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

Comme vous voulez une seule table, vous devez utiliser Single Table inheritance.

Définissez simplement une colonne discriminante comme suit:

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

Mais si vous ne souhaitez pas utiliser 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 superclasse fournissant des informations d'état et d'entités persistantes, mais qui n'est pas en soi une entité. En règle générale, le but d'une telle superclasse mappée est de définir des informations d'état et de mappage communes à plusieurs classes d'entités.

Gardez à l'esprit vous ne pouvez pas utiliser simultanément @Entity et @MappedSuperclass.

82
Arthur Ronald

@MappedSuperclass est travaillé pour moi. J'avais du mal à mapper une vue sur 2 objets qui sont des classes parent et enfant. Ma vue est jointe de 2 tables. Les clés primaires des deux tables sont présentes dans la vue. @DiscriminatorColumn ne fonctionne pas pour moi, car il requiert une colonne exclusivement réservée au type de données de l'objet et renvoie également 'repeated Column in object exception' que je n'ai pas pu résoudre. 

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

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

@Entity
@Table(name="view_name")

et utilisé un objet sub class pour extraire les données de la vue. C'est tout. 

L'héritage dans les annotations d'hibernation pour la table jointe sans l'aide de @DiscriminatorColumn a fonctionné pour moi.

5
Amirtharaj

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

Vérifiez this

0
lalit