2008-11-29 13 views
12

Rozważam użycie Adnotacji do zdefiniowania moich mapowań Hibernuj, ale mam problem: chcę zdefiniować wspólne pola (w tym pole ID), ale chcę, aby różne tabele miały różne strategie generowania identyfikatorów:Jak zastąpić strategię GenerationType przy użyciu adnotacji Hibernuj/JPA?

@MappedSuperclass 
public abstract class Base implements Serializable { 
    @Id 
    @Column(name="ID", nullable = false) 
    private Integer id; 
    public Integer getId(){return id;} 
    public void setId(Integer id){this.id = id;} 
    ... 
} 

@Entity 
@Table(name="TABLE_A") 
public class TableA extends Base { 
    // Table_A wants to set an application-defined value for ID 
    ... 
} 

@Entity 
@Table(name="TABLE_B") 
public class TableB extends Base { 
    // How do I specify @GeneratedValue(strategy = AUTO) for ID here? 
    ... 
} 

Czy jest jakiś sposób, aby to zrobić? Próbowałem w tym następujące w TableB ale hibernacji sprzeciwił się moim posiadające tej samej kolumnie dwa razy i wydaje się źle:

@Override // So that we can set Generated strategy 
@Id 
@GeneratedValue(strategy = AUTO) 
public Integer getId() { 
    return super.getId(); 
} 

Odpowiedz

4

W powyższym kodzie, to wygląda jakbyś mieszanie adnotacje na polach (superklasy) oraz metody (podklasa). Hibernacja reference documentation zaleca unikanie tego i podejrzewam, że może to być przyczyną problemu. W moim doświadczeniu z Hibernate, bezpieczniejsze i bardziej elastyczne jest przypisywanie metod getter/setter zamiast pól, więc sugeruję trzymanie się tego projektu, jeśli możesz.

Jako rozwiązanie problemu, zalecamy usunięcie pola id z nadklasy Bazowej w ogóle. Zamiast tego przenieś to pole do podklas i twórz abstrakcyjne metody getId() i setId() w twojej klasie bazowej. Następnie przesuń/implementuj metody i setId() w swoich podklasach i dodawaj adnotacje do modułów pobierających z odpowiednią strategią generowania.

Mam nadzieję, że to pomoże.

3

W metodzie dziecka nie dodawaj drugiego znacznika @Id.

@Override // So that we can set Generated strategy 
@GeneratedValue(strategy = AUTO) 
public Integer getId() { 
    return super.getId(); 
} 
1

Jeśli umieścić adnotacje na getter a nie na polu, kiedy zastąpić metodę w podklasie, adnotacje umieszczone tam będzie używany zamiast tych w nadrzędnej.

2

Moja rozdzielczość:

zreorganizujesz Base klasa w:

@MappedSuperclass 
abstract class SuperBase<K> { 
    public abstract K getId(); 
} 

@MappedSuperclass 
class Base<K> extends SuperBase<K> { 
    @Id @GeneratedValue(AUTO) 
    public K getId() { ... } 
} 

Następnie można rozciąga się od podstawy do większości swoich klasach jednostki, a jeśli trzeba zastąpić @GeneratedValue, po prostu rozciągają się od SuperBase i zdefiniuj go.

+1

To całkiem elegancki sposób na zrobienie tego, pracował dla mnie! –

Powiązane problemy