Невозможно использовать генерацию ключа столбца идентификации с <union-subclass> (TABLE_PER_CLASS) - PullRequest
86 голосов
/ 27 мая 2009

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

Дает мне это исключение:

Caused by: org.hibernate.MappingException: Cannot use identity column key
generation with <union-subclass> mapping for: com.something.SuperClass

Какой самый лучший и удобный способ для меня создать идентификаторы? Я не хочу менять свою стратегию наследования.

Ответы [ 6 ]

207 голосов
/ 29 мая 2009

Проблема здесь в том, что вы смешиваете наследование "таблица на класс" и GenerationType.Auto. Рассмотрим столбец идентификаторов в MsSQL. Это основано на столбце. В стратегии «таблица на класс» вы используете одну таблицу на класс, и у каждой есть идентификатор.

Попробуйте:

@GeneratedValue(strategy = GenerationType.TABLE)

8 голосов
/ 10 марта 2013

Интересно, является ли это специфической проблемой диалекта базы данных, поскольку, просматривая учебник YouTube с PostgreSQL в качестве базовой базы данных, я увидел, что создатель видео успешно запустил приложение со стандартным @GeneratedValue. В моем случае (основной базой данных является MySQL) мне пришлось изменить стратегию @GeneratedValue на GenerationType.TABLE в точности так, как предлагает zoidbeck.

Вот видео: https://www.youtube.com/watch?v=qIdM4KQOtH8

2 голосов
/ 21 июня 2015

Согласен с ответом Зойдбека. Вам нужно изменить стратегию на:

@GeneratedValue(strategy = GenerationType.TABLE)

Но это еще не все, вам нужно создать новую таблицу, в которой будет храниться последовательность первичных ключей таблицы вашего резюме. Измените ваше отображение на

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

И новая таблица в базе данных должна выглядеть следующим образом: enter image description here

Когда вы запустите свое приложение, Hibernate вставит строку, где sequence_name будет именем сущности (SuperClass в этом примере), а значение sequence_next_hi_value будет автоматически увеличено и использовано для новых записей всех таблиц реализации подклассов .

2 голосов
/ 07 августа 2014

В нашем случае мы используем базу данных PostreSQL для разработки и производства и базу данных hsqldb в памяти для тестов. Мы используем последовательность в обоих случаях для генерации идентификатора. Очевидно, GenerationType.AUTO по умолчанию SEQUENCE для postgres, но не удалось в наших локальных тестах (по умолчанию для hsqldb должно быть что-то еще).

Таким образом, решение, которое работало для нас, явно использует GenerationType.SEQUENCE.

1 голос
/ 07 апреля 2017

вы можете использовать @MappedSuperclass для наследования

0 голосов
/ 05 сентября 2014

Между MySQL и PostgreSQL существует соответствие стандарту SQL. PostgreSQL Postgres понимает хорошее подмножество SQL92 / 99 плюс некоторые объектно-ориентированные функции для этих подмножеств. Postgres способен обрабатывать сложные процедуры и правила, такие как декларативные запросы SQL, подзапросы, представления, многопользовательская поддержка, транзакции, оптимизация запросов, наследование и массивы. Не поддерживает выбор данных в разных базах данных.

MySQL MySQL использует SQL92 в качестве основы. Работает на бесчисленных платформах. Mysql может создавать запросы, которые могут объединять таблицы из разных баз данных. Поддерживает как левое, так и правое внешнее соединение, используя синтаксис ANSI и ODBC. Начиная с MySQL 4.1, начиная с этого выпуска, MySQL будет обрабатывать подзапросы. Представления поддерживаются начиная с версии 5.

Для подробного описания, пожалуйста, посетите. http://www -css.fnal.gov / DSG / внешний / бесплатные / PgSQL-против-mysql.html

...