Nie można użyć generowania klucza kolumny identity z (TABLE PER CLASS)

Com.coś.Superklasa:

@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.coś.Podklasa:

@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.

Author: Martijn Pieters, 2009-05-27

6 answers

Problem polega na tym, że mieszasz dziedziczenie "table-per-class" I GenerationType.Auto. Rozważmy kolumnę tożsamości w MsSQL. Jest oparty na kolumnach. W strategii "table-per-class" używasz jednej tabeli na klasę i każda z nich ma ID.

Try:

@GeneratedValue(strategy = GenerationType.TABLE)

 192
Author: zoidbeck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 13:13:13

Zastanawiam się, czy jest to problem specyficzny dla dialektu bazy danych, ponieważ oglądając samouczek youtube z PostgreSQL jako bazą danych widziałem, że twórca wideo uruchamia aplikację z domyślną @ GeneratedValue. W moim przypadku (bazą danych jest MySQL) musiałem zmodyfikować strategię @ GeneratedValue do GenerationType.Stół dokładnie tak, jak proponuje zoidbeck.

Oto film: https://www.youtube.com/watch?v=qIdM4KQOtH8

 8
Author: skiabox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-10 15:52:03

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 wygenerowania id. Najwyraźniej GenerationType.AUTO domyślnie SEQUENCE dla postgres, ale nie powiodło się w naszych lokalnych testach(musi być domyślnie coś innego dla hsqldb).

Więc rozwiązanie, które działało dla nas, wyraźnie używać GenerationType.SEQUENCE.

 2
Author: Ryan Walls,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-06 21:01:58

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 trzymać główną sekwencję klucza tabeli twojego abstraktu. Zmień mapowanie na

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ConfirmationCodeGenerator")
@TableGenerator(table = "SEQUENCES", name = "ConfirmationCodeGenerator")
public long getConfirmationCode() {
   return confirmationCode;
}

I nowa tabela w bazie danych powinna wyglądać następująco: Tutaj wpisz opis obrazka

Po uruchomieniu aplikacji, Hibernate wstawi wiersz, w którym sequence_name będzie nazwą encji (SuperClass w tym przykładzie), a sequence_next_hi_value wartość zostanie automatycznie zwiększona i użyta do nowe rekordy wszystkich tabel implementujących podklasy.

 2
Author: Gondy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-21 13:32:36

istnieje zgodność ze standardem SQL pomiędzy MySQL i PostgreSQL. PostgreSQL Postgres rozumie dobry podzbiór SQL92 / 99 oraz pewne obiektowe funkcje do tych podzbiorów. Postgres jest w stanie obsługiwać złożone procedury i reguły, takie jak deklaratywne zapytania SQL, zapytania podrzędne, widoki, obsługa wielu użytkowników, transakcje, optymalizacja zapytań, dziedziczenie i tablice. Nie obsługuje wybierania danych w różnych bazach danych.

MySQL MySQL używa SQL92 jako jego fundamentem. Działa na niezliczonych platformach. Mysql może konstruować zapytania, które mogą łączyć tabele z różnych baz danych. Obsługuje zarówno lewe, jak i prawe złączenia zewnętrzne przy użyciu składni ANSI i ODBC. Począwszy od MySQL 4.1 od tego wydania, MySQL będzie obsługiwać zapytania podrzędne. Widoki obsługiwane od wydania 5.

Szczegółowy opis znajdziesz na stronie. http://www-css.fnal.gov/dsg/external/freeware/pgsql-vs-mysql.html

 0
Author: Coderac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-05 15:14:54

Możesz użyć @MappedSuperclass do dziedziczenia

 0
Author: leimbag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-07 02:08:16