2012-11-02 7 views
14

Ich verwende JPA in meiner Anwendung. In einer der Tabelle habe ich keinen Primärschlüssel verwendet (ich weiß, dass es ein schlechtes Design ist).JPA-Fehler: Die Entität hat kein Primärschlüssel-Attribut definiert

Nun ist die erzeugte Einheit wird, wie unten erwähnt:

@Entity 
@Table(name="INTI_SCHEME_TOKEN") 
public class IntiSchemeToken implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Column(name="CREATED_BY") 
    private String createdBy; 

    @Temporal(TemporalType.DATE) 
    @Column(name="CREATED_ON") 
    private Date createdOn; 

    @Column(name="SCH_ID") 
    private BigDecimal schId; 

    @Column(name="TOKEN_ID") 
    private BigDecimal tokenId; 

    public IntiSchemeToken() { 
    } 

    public String getCreatedBy() { 
     return this.createdBy; 
    } 

    public void setCreatedBy(String createdBy) { 
     this.createdBy = createdBy; 
    } 

    public Date getCreatedOn() { 
     return this.createdOn; 
    } 

    public void setCreatedOn(Date createdOn) { 
     this.createdOn = createdOn; 
    } 

    public BigDecimal getSchId() { 
     return this.schId; 
    } 

    public void setSchId(BigDecimal schId) { 
     this.schId = schId; 
    } 

    public BigDecimal getTokenId() { 
     return this.tokenId; 
    } 

    public void setTokenId(BigDecimal tokenId) { 
     this.tokenId = tokenId; 
    } 



} 

hier in meinem Projekt Eclipse IDE zeigt ERROR Zeichen (rot gefärbt Kreuz) auf dieser Klasse und der Fehler "Das Unternehmen hat keinen Primärschlüssel Attribut definiert ".

Kann mir jemand sagen, wie man eine Entität ohne Primärschlüssel erstellen?

Danke.

+0

http://stackoverflow.com/questions/1519078/oracle-legacy-table-without-good-pk-how-to-hibernate – gavenkoa

Antwort

18

Sie können nicht. Eine Entität MUSS eine eindeutige, unveränderbare ID haben. Es muss nicht als Primärschlüssel in der Datenbank definiert werden, aber das Feld oder die Gruppe von Feldern muss die Zeile eindeutig identifizieren und ihr Wert darf sich nicht ändern.

Wenn also ein Feld in Ihrer Entität oder eine Gruppe von Feldern in Ihrer Entität diese Kriterien erfüllt, machen Sie es (oder sie) zur ID der Entität. Wenn beispielsweise ein Benutzer zwei Instanzen am selben Tag nicht erstellen kann, können Sie [createdOn, createdBy] die ID der Entität angeben.

Natürlich ist dies eine schlechte Lösung, und Sie sollten wirklich Ihr Schema ändern und eine automatisch generierte, einspaltige ID in der Entität hinzufügen.

+3

+1. Wenn Sie es aus Sicht der Geschäftslogik nicht benötigen, fügen Sie einfach eine künstliche ID-Spalte hinzu, um ORM glücklich und Ihr Leben einfacher zu machen. –

+0

@ Danke für die Antwort. Ich habe createdOn als Primärschlüssel in der Entity deklariert, nicht in der DB. Es funktioniert jetzt gut. –

+0

"Es muss nicht als Primärschlüssel in der Datenbank definiert werden". Ich protestiere dagegen. Wenn dies aufgrund der Existenz einer anderen Primärschlüsseldefinition erforderlich ist, muss sie verwendet werden. Andernfalls, wenn der implizite Vorschlag darin besteht, einen Sekundärindex zu definieren, dann OK, aber ohne einen Index zu gehen, wird Ihre Datenbank zerstört. –

6

Wenn Sie eine Klasse ohne Primärschlüssel definieren müssen, sollten Sie diese Klasse als Embeddable-Klasse kennzeichnen. Andernfalls sollten Sie den Primärschlüssel für alle Entitäten angeben, die Sie definieren.

0

Eine andere Lösung ohne Hibernate

Wenn - Sie müssen nicht PK auf der Tisch haben - es ist eine logische Kombination von Spalten, die PK sein könnte (nicht erforderlich, wenn Sie irgendeine Art von Rowid verwenden) - aber einige der Spalten sind NULLable, so dass Sie wirklich keine PK wegen der DB-Einschränkung erstellen können - und Sie können die Tabellenstruktur nicht ändern (würde einfügen/select-Anweisungen mit keine explizit aufgeführten Spalten bei Legacy-Code)

dann können Sie den folgenden Trick versuchen - erstellen Sie eine Sicht in der Datenbank mit virtuelle Spalte, die den Wert von verketteten logischen Schlüsselspalten hat ('A =' || a || 'B =' || 'C =' c ..) oder rowid - erstellen Sie Ihre JPA-Entity-Klasse von dieser Ansicht - markieren Sie die virtuelle Spalte mit @Id Annotation

Das ist es. Das Aktualisieren/Löschen von Datenoperationen ist ebenfalls möglich (nicht einfügen), aber ich würde sie nicht verwenden, wenn die virtuelle Schlüsselspalte nicht aus rowid besteht (um vollständige Suchvorgänge durch die DB-Tabelle zu vermeiden)

P.S. Die gleiche Idee wird teilweise in der verknüpften Frage beschrieben.

3

Sie ausschalten (ändern) Validierung, die hinzugefügt wurde.

Gehen Sie zu Workspace-Einstellungen 'Java Persistence-> JPA-> Fehler/Warnungen' als nächstes 'Typ' und ändern Sie 'Entity hat keinen Primärschlüssel' zu 'Warning'.

0

Sie müssen den Primärschlüssel erstellen. Wenn kein zulässiges Feld gefunden wird, erstellen Sie eine automatische Inkrement-ID.

CREATE TABLE fin_home_loan (
    ID int NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (ID)); 
Verwandte Themen