Могу ли я смешивать таблицу на подкласс и <map>в одной таблице в Hibernate? - PullRequest
0 голосов
/ 06 августа 2009

Я пытаюсь отобразить объектную модель для «Акции»; клиент вводит промо-код во время регистрации.

Различные промо-коды могут иметь различные типы «преимуществ», то есть то, что мы даем клиенту. Например: промо-код XYZ123 предоставит клиенту бесплатные минуты в его учетной записи, в то время как другой промо-код предложит различные скидки на различные тарифные планы, которые пользователь может выбрать при регистрации.

В моей модели предметной области я смоделировал различные типы преимуществ как подклассы с абстрактным суперклассом, который имеет общие свойства. Я выбрал моделирование различных типов в качестве подклассов, поскольку для некоторых типов преимуществ потребуются разные свойства.

public abstract class Benefit {
    //getters/setters for common attributes
}

public class FreeMinutesBenefit extends Benefit {
    public int getFreeMinutes() {...}
    public void setFreeMinutes(int minutes} {...}
}

public class PriceDiscountBenefit extends Benefit {
    public Map<Plan, BigDecimal> getDiscountMap() {...}
    public void setDiscountMap(Map<Plan, BigDecimal> map) {...}
}

Грубая схема SQL:

-- Parent table, maps promotion to benefits
create table Promo_Benefit (
    map_id integer auto-generated PRIMARY KEY,
    promo_id integer references PROMOTION(promo_id),
    type_id integer references BENEFIT_TYPES(type_id)
);

create table BenefitDetails_FreeMinutes (
    map_id integer PRIMARY KEY,
    minutes integer not null,
    FOREIGN KEY (map_id) references Promo_Benefit(map_id)
);

create table BenefitDetails_PriceDiscount (
    map_id integer references Promo_Benefit(map_id),
    plan_id integer references Plans(plan_id),
    reduced_price numeric not null,
    PRIMARY KEY (map_id, plan_id)
    FOREIGN KEY (map_id) references Promo_Benefit(map_id)
);

Я могу успешно отобразить основные свойства каждого подкласса в моих файлах отображения Hibernate, но у меня возникают проблемы с выяснением, как сопоставить связь между подклассом PriceDiscountBenefit и классом Plan.

Я полагаю, это потому, что первичный ключ таблицы подклассов (BenefitDetails_PriceDiscount) - это не просто столбец map_id - другими словами, несколько строк в этой таблице подклассов образуют единую сущность PriceDiscountBenefit. Из того, что я вижу, кажется, что поддержка таблицы на подкласс в Hibernate предназначена для случаев, когда одна строка в таблице подклассов отображается на одну строку в родительской таблице - и отображение <map> должно ссылаться на вторая таблица, которая содержит ключи / значения.

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

1 Ответ

1 голос
/ 06 августа 2009

Стратегия Table-per-subclass означает, что у вас будет таблица для каждого класса в вашей иерархии (включая абстрактные классы, если таковые имеются), и все они будут иметь общий первичный ключ. В вашем случае это означает, что у вас будет отдельная таблица для каждого из классов Benefit, FreeMinutesBenefit и PriceDiscountBenefit. Ваши имена таблиц немного сбивают с толку, и структура таблицы несколько несовместима с таблицей на подкласс.

Предполагая, что map_id является общим первичным ключом, таблица BenefitDetails_PriceDiscount должна определять его как таковой. plan_id принадлежит другому ('mapping ) table that will hold a map between PriceDiscountBenefit , Plan` и десятичному значению. Другими словами:

create table BenefitDetails_PriceDiscount (
        map_id integer PRIMARY KEY,
        ... /* any other attributes, perhaps? */
        FOREIGN KEY (map_id) references Promo_Benefit(map_id)
);

create table BenefitDetails_PriceDiscount_Map (
        map_id integer references Promo_Benefit(map_id),
        plan_id integer references Plans(plan_id),
        reduced_price numeric not null,
        PRIMARY KEY (map_id, plan_id)
        FOREIGN KEY (map_id) references Promo_Benefit(map_id)
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...