2013-05-10 2 views
1

Я сопоставляю устаревшую базу данных, одна таблица которой естественно сопоставляется с иерархией наследования с использованием сопоставления SINGLE_TABLE с использованием столбца дискриминатора. Проблема в том, что существует огромное количество значений дискриминатора! (Кроме того, иногда добавляются новые, и приложение автоматически выбирает их в полиморфных запросах). С точки зрения моего приложения, я хотел бы рассматривать подавляющее большинство этих разных типов одинаково (т. Е. Просто сопоставить их с базовым классом в иерархии наследования). Однако, для небольшого числа, я хотел бы сопоставить определенный подкласс. Проблема в том, что JPA, по-видимому, требует, чтобы я предоставлял один конкретный @DiscriminatorValue в базовом классе (иначе он генерирует значение по умолчанию).JPA (Hibernate) Значение SINLE_TABLE наследования по всем признакам?

Чтобы быть конкретным:

@Entity 
@Table("products") 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name = "product_type") 
@DiscriminatorValue(*anything not specified elsewhere!*) 
public class Product { 
    ... 
    public double calculateMarkup() { ... default impl ... } 
} 
@Entity 
@DiscriminatorValue("ProductA") 
public class ProductA extends Product { 
    ... 
    @Override public double calculateMarkup() { ... specific impl ... } 
} 

Есть ли способ, чтобы отобразить это элегантно в JPA (или Hibernate 3,3-определенными расширениями)? Единственное решение, с которым я могу прийти, это отказаться от наследования и отобразить столбец как нормальное поле, которое внутренне делает это значение для особых случаев, но это кажется неестественным и немного грязным.

+0

«за горсть, я хотел бы карту к определенному подклассу» - как они отличаются от основания класс? Уточняют ли члены-члены базовый класс? –

+0

Без полей, просто по-разному. –

ответ

1

Есть ли способ, чтобы отобразить это элегантно в JPA

Нет, не то, что я знаю. Если проблема связана с уровнем данных (например, данными или базой данных), я попытаюсь решить проблему на этом уровне. Попробуйте любого из двух ниже подходов:

  • создать представление в базе данных, которая идентична таблице за исключением того, что «ничего не указанное в другом месте» отображаются * для дискриминатора
  • по умолчанию написать на вставке/update на таблице Product, которая фиксирует значения дискриминатора для каждого reacord *.

* Oracle, например, предоставляет DECODE для отображения значений из диапазона A в диапазон B, если-то-else-like.

+0

Интересное решение. Я не знаю, почему мне это не показалось. Случаи, которые хотят, чтобы подклассы также были единственными случаями, которые мы когда-либо вставляли/обновляли, так что это будет работать очень хорошо. Благодарю. –

0

Посмотрите в использовании @ClassExtractor: http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Inheritance#Example:_Using_ClassExtractor_do_define_inheritance

Что-то вроде

public class ProductExtractor implements ClassExtractor { 
    public void extractClassFromRow(Record row, Session session) { 
     if (row.get("product_type").equals("ProductA")) { 
      return ProductA.class; 
     } 
     return Product.class; 
    } 
} 

затем написать настройщиков для ваших классов и аннотирования с ними.

1

Я решил такую ​​же проблему, используя @DiscriminatorFormula (http://lauraliparulo.altervista.org/hibernate-inheritance/). Формула дискриминатора возвращает

CASE WHEN (product_type!='ProductA') THEN 'LEGACY' 
ELSE product_type 

и сущность продукта имеет @DiscriminatorValue («LEGACY»)

Смежные вопросы