2012-11-02 13 views
14

Używam JPA w mojej aplikacji. W jednej z tabel nie użyłem klucza podstawowego (znam jego zły projekt).Błąd JPA: Podmiot nie ma zdefiniowanego atrybutu klucza głównego.

Teraz generowane podmiot, o którym mowa poniżej:

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



} 

w moim projekcie Eclipse IDE pokazuje znak ERROR (RED kolorowe krzyż) w tej klasie, a błąd jest "Jednostka ma klucz podstawowy atrybut zdefiniowany ".

Czy ktoś może mi powiedzieć, jak utworzyć podmiot bez klucza podstawowego?

Dzięki.

+0

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

Odpowiedz

18

Nie możesz. Jednostka MUSI mieć unikalny, niezmienny identyfikator. Nie musi być zdefiniowany jako klucz podstawowy w bazie danych, ale pole lub zestaw pól musi jednoznacznie identyfikować wiersz, a jego wartość może się nie zmieniać.

Tak więc, jeśli jedno pole w twojej encji lub jeden zestaw pól w twojej jednostce spełnia te kryteria, zrób (lub im) identyfikator jednostki. Na przykład, jeśli nie ma możliwości, aby użytkownik mógł utworzyć dwie instancje w tym samym dniu, można uczynić [createdOn, createdBy] identyfikatorem encji.

Oczywiście jest to złe rozwiązanie i powinieneś naprawdę zmienić swój schemat i dodać wygenerowany automatycznie identyfikator o pojedynczej kolumnie w encji.

+3

+1. Jeśli nie jest to potrzebne z punktu widzenia logiki biznesowej, wystarczy dodać kolumnę sztuczne ID aby ORM szczęśliwy i Twoje życie łatwiejszym. –

+0

@ Dzięki za odpowiedź. Zadeklarowałem createdOn jako klucz podstawowy w jednostce spoza DB. Teraz działa dobrze. –

+0

„To nie musi być zdefiniowany jako klucz podstawowy w bazie danych”. Sprzeciwiam się temu. Jeśli jest to konieczne ze względu na istnienie innej definicji klucza głównego, musi być użyte. W przeciwnym razie, jeśli niejawna sugestia jest określenie indeksu wtórnego, a następnie OK, ale dzieje bez indeksu w ogóle, zabijesz swoją bazę danych. –

6

Jeśli chcesz zdefiniować klasę bez klucza podstawowego, powinieneś oznaczyć tę klasę jako klasę Embedded. W przeciwnym razie powinieneś dać klucz podstawowy dla wszystkich definiowanych przez ciebie podmiotów.

0

Innym rozwiązaniem bez Hibernate

Jeśli - nie masz PK na stole - istnieje logiczne połączenie kolumn, które mogą być PK (nie jest konieczne, jeśli można użyć jakiegoś rowid) - ale niektóre kolumny są NULLABLE, więc naprawdę nie można utworzyć PK z powodu ograniczenia DB - i nie można modyfikować struktury tabeli (złamałoby instrukcje wstawiania/wyboru bez jawnie wyświetlanych kolumn w starszym kodzie)

następnie możesz wypróbować następującą sztuczkę - utwórz widok w bazie danych z wirtualna kolumna, która ma wartość połączonych kolumn logicznych kluczy ('A =' || a || 'B =' || 'C =' c ..) lub wierszid - utwórz swoją klasę jednostek JPA według tego widoku - zaznacz wirtualną kolumnę z adnotacją @Id

To wszystko. Aktualizuj/usuń operacje danych są również możliwe (nie wstawiaj), ale nie użyłbym ich, jeśli kolumna klucza wirtualnego nie jest utworzona z rowid (aby uniknąć wyszukiwania pełnymi skanami przez tabelę DB)

P.S. Ta sama idea jest częściowo opisana w połączonym pytaniu.

3

Można wyłączyć (zmień) walidację, który został dodany.

Przejdź do preferencji obszaru roboczego 'Java Persistence-> JPA-> Errors/Warnings' next 'Type "i zmień' Entity has no primary key 'na' Warnning '.

0

Musisz utworzyć klucz podstawowy, jeśli nie znaleziono każdy kwalifikuje pole następnie stworzyć auto przyrostu Id.

CREATE TABLE fin_home_loan (
    ID int NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (ID)); 
Powiązane problemy