Hibernate 4: сохраняются значения столбца дискриминатора InheritanceType.JOINED - PullRequest
10 голосов
/ 03 ноября 2011

У меня есть простая ОБЪЕДИНЕННАЯ иерархия документов:

CREATE TABLE Documents
(
  id INTEGER NOT NULL,
  discriminator ENUM('official','individual','external') NOT NULL,
  file_name VARCHAR(200) NOT NULL,
  PRIMARY KEY (id)
);

CREATE SystemDocuments
(
  id INTEGER NOT NULL,
  binary_data BLOB NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (id) REFERENCES Documents (id)
);

CREATE ExternalDocuments
(
  id INTEGER NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (id) REFERENCES SystemDocuments (id)
);

Как вы можете видеть, все вспомогательные таблицы делят один и тот же идентификатор из таблицы документов.Кроме этого SystemDocuments добавляет столбец binary_data, а ExternalDocuments не добавляет новых свойств.(Также обратите внимание, что в иерархии есть две другие конкретные вложенные таблицы, обозначенные 'official' и 'individual', которые здесь не имеют отношения.)

Вот сопоставления для приведенных выше таблиц:

Document.java :

@Entity
@Table(name = "Documents")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
//@DiscriminatorOptions(force = true) // <-- Hibernate 4-specific annotation not inserting discriminator values
public abstract class Document implements Serializable
{
    @Id
    @Column
    protected Integer id;

    @Column(name = "file_name")
    protected String fileName;

    ...
}

SystemDocument.java :

@Entity
@Table(name = "SystemDocuments")
public abstract class SystemDocument extends Document
{
    @Lob
    @Column(name = "binary_data")
    protected byte[] binaryData;

    ...
}

ExternalDocument.java :

@Entity
@Table(name = "ExternalDocuments")
@DiscriminatorValue(value = "external")
public class ExternalDocument extends SystemDocument
{
    ...
}

Предполагается, что последний класс сопоставляется со значением столбца дискриминатора Документов 'external'.При нахождении сущностей через EntityManager.find дискриминаторы возвращаются корректно, в действительности потому, что дискриминаторы моих тестовых данных были вставлены в БД правильно.

Теперь я использую следующий код для вставки новых документов / файлов всистема через JPA и загрузчик файлов:

...

UploadedFile uf = event.getUploadedFile();

// set ID, file name, and binary data
ExternalDocument detachedExternalDocument =
    new ExternalDocument(1234567, uf.getName(), uf.getData());

docService.create(detachedExternalDocument);

Однако при проверке БД я вижу, что Hibernate не вставляет значение дискриминатора 'external' в * 1038 таблицы Documents* column.

В прошлом были проблемы по этому поводу, см. https://hibernate.onjira.com/browse/ANN-140 и более поздние версии для Hibernate 4 https://hibernate.onjira.com/browse/HHH-4358,, поэтому есть вероятность, что он будет работать именно так.

Затем я нашел http://docs.jboss.org/hibernate/core/4.0/javadocs/org/hibernate/annotations/DiscriminatorOptions.html в текущих документах API Hibernate 4, но он не работает (см. @DiscriminatorOptions в классе Document).

Как я могу получить Hibernate 4 ввставьте дискриминаторы , используя необработанные аннотации ?

Примечание : я не хочу отображать столбец дискриминатора как обычный столбец.

1 Ответ

20 голосов
/ 20 декабря 2011

Прежде всего, этот вопрос является дубликатом Дискриминатор в InheritanceType.JOINED .

Похоже, что сохраняющиеся значения дискриминатора в наследовании JOINED не , требуемые спецификацией JPA. Вот что я получил от члена экспертной группы JPA по электронной почте:

Спецификация не требует, чтобы реализация использовала столбцы дискриминатора для реализации наследования JOINED, однако предполагается, что, если задан @DiscriminatorColumn, он будет использоваться, то есть значения будут записаны. Мы не утверждаем явно, что если в коде указан @DiscriminatorColumn, он должен использоваться, точно так же, как мы не заявляем явно, что если указан @Column или @JoinColumn, значения должны храниться в таблице, но есть только так много, что мы можем или должны указать. На самом низком уровне некоторые законы физики и разума просто предполагаются.

Проблема, с которой мы столкнулись, долгое время была проблемой с Hibernate, см. Здесь:

https://hibernate.atlassian.net/browse/ANN-140

Комментарий отклонен:

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

В конце концов, только стратегии SINGLE_TABLE требуется столбец дискриминатора, без которого JOINED может быть реализован . В настоящее время проблема с Hibernate заключается в том, что он вызывает несогласованность данных при сохранении дочерних объектов в наследовании JOINED, отображаемом с помощью @DiscriminatorColumn, хотя в спецификации JPA рекомендуется сохранять значения дискриминатора, если с JOINED используется дискриминатор. Подробнее в RFE здесь:

https://hibernate.atlassian.net/browse/HHH-6911

...