2016-04-08 4 views
2

Ich möchte eine übergeordnete Klasse haben, die für alle Dokumenttypen gemeinsam ist:Wie löst man 'Kein Primärschlüssel angegeben' für eine Entität, die von einer anderen Entität (JPA) erbt?

@Entity 
public abstract class Doc implements Serializable 
{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    protected long docId; 

    public long getDocId() 
    { 
     return docId; 
    } 

    public void setDocId(long docId) 
    { 
     this.docId = docId; 
    } 

} 

Und ich möchte für jeden doc Typ Kind Klassen haben:

@Entity 
@Table(name = "DocTypeA") 
public class DocTypeA extends Doc implements Serializable 
{ 
    // other child fields 
} 

Aber es gibt einen Fehler aus und sagt, dass DocTypeA benötigt einen Primärschlüssel. Wie kann ich den Primärschlüssel isolieren und in die Superklasse einordnen? Weil alle Unterklassen dasselbe ID-Feld haben.

Ich benutze EclipseLink.

Und meine andere Frage ist: Warum muss ich @Entity in der abstrakten Klasse setzen? Da es sich um eine abstrakte Klasse handelt, kann sie nicht instanziiert werden. Worum geht es also, sie als Entität zu kennzeichnen? Ist es wirklich notwendig? Ich werde die Superklasse nicht bestehen lassen. Ich brauche es nur, um den in allen Unterklassen üblichen Code zu isolieren.

Exception Description: Entity class [class repository.DocTypeA] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy. 
+0

Was ist die genaue und vollständige Fehler Stack Trace? Wie soll Ihr Datenbankschema aussehen? –

+0

Sind Sie sicher, dass die Doc-Klasse tatsächlich mit '@ Entity' versehen ist, wenn Sie diese Ausnahme erhalten? –

+1

Lesen Sie http://StackOverflow.com/questions/9667703/jpa-implementing-model-hiearchy-mappedsuperclass-vs-inheriterence –

Antwort

5

Nach den @MappedSuperclassofficial JavaDoc der Anmerkung::

Bezeichnet eine Klasse, deren Zuordnungsinformation an die Einheiten angewandt

die Stapelüberwachung ist lang wird relevanter Teil unterhalb kleben die von ihm erben. Für eine zugeordnete Superklasse ist keine separate Tabelle definiert.

was Sie suchen. Somit können abstract Klassen einfach für allgemeine Attribute von Entitäten verwendet werden, was in den meisten Fällen ein Primärschlüssel oder eine DB-generierte Objektkennung ist. Mit Anmerkungen versehene Felder dieser abstrakten Klasse werden dann nur für konkrete Unterklassen zugeordnet werden:

Eine Klasse bezeichnet mit der MappedSuperclass Anmerkung kann außer auf die gleiche Art und Weise als eine Einheit abgebildet wird, dass die Zuordnungen gelten nur für ihre Unterklassen, da keine Tabelle existiert für die zugeordnete Oberklasse selbst. Bei Anwendung auf die Unterklassen gelten die übernommenen Zuordnungen im Kontext der Unterklasse-Tabellen.

tauschen @Entity Anmerkung in der abstrakten Klasse Doc wie so:

@MappedSuperclass 
public abstract class Doc implements Serializable 
{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    protected long docId; 
    //... 
} 

und Sie sollten gut zu gehen.

Ich hoffe, es hilft.