2012-11-02 2 views
14

Sto usando JPA nella mia applicazione. In una delle tabelle, non ho usato la chiave primaria (so che è una cattiva progettazione).Errore JPA: l'entità non ha un attributo chiave primaria definito

Ora l'entità generato è come detto di seguito:

@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; 
    } 



} 

Ecco Nel mio progetto, IDE Eclipse mostra segno di ERRORE (di colore rosso croce) su questa classe e l'errore è "L'entità non ha alcuna chiave primaria attributo definito ".

Qualcuno può dirmi, Come creare un'entità senza chiave primaria?

Grazie.

+0

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

risposta

18

Non è possibile. Un'entità DEVE avere un ID unico e immutabile. Non deve essere definito come una chiave primaria nel database, ma il campo o l'insieme di campi deve identificare in modo univoco la riga e il suo valore potrebbe non cambiare.

Quindi, se un campo nell'entità o un gruppo di campi nell'entità soddisfa questi criteri, renderlo (o loro) l'ID dell'entità. Ad esempio, se non è possibile che un utente possa creare due istanze nello stesso giorno, è possibile creare [createdOn, createdBy] l'ID dell'entità.

Ovviamente questa è una soluzione non valida, e si dovrebbe davvero cambiare lo schema e aggiungere un ID autogenerato, a colonna singola nell'entità.

+3

+1. Se non ne hai bisogno dal punto di vista della logica aziendale, basta aggiungere una colonna ID artificiale per rendere l'ORM felice e la tua vita più facile. –

+0

@Grazie per la risposta. Ho dichiarato createdOn come chiave primaria nell'entità non nel DB. Funziona bene ora. –

+0

"Non deve essere definito come chiave primaria nel database". Mi oppongo a questo. Se questo è necessario a causa dell'esistenza di un'altra definizione di chiave primaria, deve essere utilizzato. Altrimenti, se il suggerimento implicito è quello di definire un indice secondario, allora OK, ma senza un indice, ucciderai il tuo database. –

6

Se è necessario definire una classe senza chiave primaria, è necessario contrassegnarla come classe incorporabile. Altrimenti dovresti fornire la chiave primaria per tutte le entità che stai definendo.

0

Un'altra soluzione senza Hibernate

Se - non si dispone di PK sul tavolo - v'è una combinazione logica di colonne che potrebbe essere PK (non necessario se è possibile utilizzare una sorta di identificativo) - ma alcune delle colonne sono NULLable quindi non è possibile creare PK a causa della limitazione del DB - e non è possibile modificare la struttura della tabella (si interromperanno le istruzioni insert/select senza colonne esplicitamente elencate sul codice precedente)

allora puoi provare il seguente trucco - creare una vista al database con colonna virtuale che ha valore di colonne chiave concatenate di chiavi ('A =' || a || 'B =' || 'C =' c ..) o rowid - crea la tua classe di entità JPA con questa vista - contrassegna la colonna virtuale con l'annotazione @Id

Questo è tutto. Anche le operazioni di aggiornamento/cancellazione dei dati sono possibili (non inserite) ma non le userei se la colonna della chiave virtuale non è composta da rowid (per evitare ricerche di scansione complete dalla tabella DB)

P.S. La stessa idea è in parte descritta nella domanda collegata.

3

È possibile disattivare la convalida (cambiamento) che è stata aggiunta.

Passare alle preferenze dell'area di lavoro 'Persistenza Java-> JPA-> Errori/Avvisi' successivo 'Tipo' e modificare 'Entità non ha chiave primaria' per 'Avvisare'.

0

È necessario creare la chiave primaria, se non è stato trovato alcun campo idoneo, quindi creare l'ID di incremento automatico.

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