com.something.SuperClass:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class SuperClass implements Serializable {
private static final long serialVersionUID = -695503064509648117L;
long confirmationCode;
@Id
@GeneratedValue(strategy = GenerationType.AUTO) // Causes exception!!!
public long getConfirmationCode() {
return confirmationCode;
}
public void setConfirmationCode(long confirmationCode) {
this.confirmationCode = confirmationCode;
}
}
com.something.SubClass:
@Entity
public abstract class Subclass extends SuperClass {
private static final long serialVersionUID = 8623159397061057722L;
String name;
@Column(nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Daje mi ten wyjątek:
Caused by: org.hibernate.MappingException: Cannot use identity column key
generation with <union-subclass> mapping for: com.something.SuperClass
Jaki jest najlepszy i najwygodniejszy sposób generowania identyfikatorów? Nie chcę zmieniać mojej strategii dziedziczenia.
hibernate
inheritance
jpa
class-table-inheritance
Martijn Pieters
źródło
źródło
Zastanawiam się, czy jest to problem specyficzny dla dialektu bazy danych, ponieważ oglądając samouczek YouTube z PostgreSQL jako bazową bazą danych, zobaczyłem, że twórca wideo pomyślnie uruchomił aplikację z domyślną @GeneratedValue. W moim przypadku (bazową bazą danych jest MySQL) musiałem zmodyfikować strategię @GeneratedValue na GenerationType.TABLE dokładnie tak, jak proponuje zoidbeck.
Oto wideo: https://www.youtube.com/watch?v=qIdM4KQOtH8
źródło
GenerationType.SEQUENCE
. Dlatego działa tam automatycznie. Nie ma to absolutnie nic wspólnego z PostgreSQLINHERITS
.Zgadzam się z odpowiedzią Zoidbecka. Musisz zmienić strategię na:
@GeneratedValue(strategy = GenerationType.TABLE)
Ale to nie wszystko, musisz utworzyć nową tabelę, która będzie przechowywać sekwencję kluczy podstawowych tabeli streszczenia. Zmodyfikuj mapowanie do
@Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "ConfirmationCodeGenerator") @TableGenerator(table = "SEQUENCES", name = "ConfirmationCodeGenerator") public long getConfirmationCode() { return confirmationCode; }
A nowa tabela w bazie danych powinna wyglądać następująco:
Po uruchomieniu aplikacji Hibernate wstawi wiersz, w którym
sequence_name
będzie nazwa jednostki (SuperClass
w tym przykładzie), asequence_next_hi_value
wartość zostanie automatycznie zwiększona i wykorzystana do nowych rekordów wszystkich implementujących tabel podklas.źródło
W naszym przypadku używamy bazy danych PostreSQL do tworzenia i produkcji oraz bazy danych hsqldb w pamięci do testów. W obu przypadkach używamy sekwencji do generowania identyfikatora. Wygląda na to, że
GenerationType.AUTO
domyślnie jest toSEQUENCE
postgres, ale nie powiodło się w naszych lokalnych testach (musi być domyślnie ustawione na coś innego dla hsqldb).Więc rozwiązanie, które działało dla nas, wyraźnie użyj
GenerationType.SEQUENCE
.źródło
możesz użyć @MappedSuperclass do dziedziczenia
źródło
Pomiędzy MySQL i PostgreSQL istnieje zgodność ze standardem SQL. PostgreSQL Postgres rozumie dobry podzbiór SQL92 / 99 oraz kilka funkcji obiektowych w tych podzbiorach. Postgres jest w stanie obsługiwać złożone procedury i reguły jako deklaratywne zapytania SQL, podzapytania, widoki, obsługę wielu użytkowników, transakcje, optymalizację zapytań, dziedziczenie i tablice. Nie obsługuje wybierania danych z różnych baz danych.
MySQL MySQL używa SQL92 jako podstawy. Działa na niezliczonych platformach. MySQL może konstruować zapytania, które mogą łączyć tabele z różnych baz danych. Obsługuje lewe i prawe sprzężenia zewnętrzne przy użyciu składni ANSI i ODBC. Począwszy od MySQL 4.1 od tego wydania, MySQL będzie obsługiwał podzapytania. Widoki obsługiwane od wersji 5.
Szczegółowy opis można znaleźć na stronie. http://www-css.fnal.gov/dsg/external/freeware/pgsql-vs-mysql.html
źródło