Hibernate @ElementCollection - требуется лучшее решение - PullRequest
3 голосов
/ 22 мая 2011

Я использую Hibernate 3.5.a-Final в качестве ORM-Layer в веб-приложении. У меня есть несколько Бинов с одним и тем же фрагментом кода, который заставляет меня думать, что этот дизайн не самый лучший. Но я не могу понять, как реализовать лучший в спящем режиме.

Требования

  • Несколько классов должны содержать локализованные описания в нескольких локалях
  • Они должны быть сохранены в БД
  • Они должны быть доступны для поиска по подстроке для всех локалей (показать, если seachstring является подстрокой любого описания)
  • Локализованные описания должны запрашиваться без загрузки главного объекта (по идентификатору главного объекта, -type и locale)

Текущее решение (не решает последнее требование)

Каждый класс содержит HashMap, аннотированный как

@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name = "localized[X]Descriptions", joinColumns = @JoinColumn(name = "id"))
@MapKeyJoinColumn(name = "locale")
public Map<Locale, String> getLocalizedDescriptions() {
    return localizedDescriptions;
}

[X] имя класса

Для каждого класса есть дополнительная таблица (генерируется hibernate)

create table localized[X]Descriptions (
    id integer not null,
    localizedDescriptions varchar(255),
    localizedDescriptions_KEY varchar(255),
    primary key (id, localizedDescriptions_KEY)
)

По какой-то причине @MapKeyJoinColumn игнорируется ...

То, что я бы предпочел, было бы одной такой таблицей:

create table localizedDescriptions (
    class varchar(255) not null,
    id integer not null,
    locale varchar(50) not null,
    description varchar(255) not null,
    primary key (class, id, locale)
)

Было бы большим плюсом, если бы реализация была запрашиваемой с использованием критерия-API (который, насколько я знаю, несовместим с @ElementCollection s). Но я не могу понять, как это реализовать. Любые указатели будут очень рады

1 Ответ

2 голосов
/ 24 мая 2011

Я нашел свое решение ...

Я просто использую

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="masterClass", discriminatorType=DiscriminatorType.INTEGER)
@Table(name="localizedDescriptions")
public class LocalizedDescriptions{

    private Integer id;
    private Locale locale;
    private String description;

        [Getters, Setters]
}

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

@Entity
public class LocalizedSomeDescription extends LocalizedDescription {

    private Some master;

    /**
     * @return the master
     */
    @ManyToOne
    public Some getMaster() {
        return master;
    }

Который привык так:

@Table
@Entity
public class Some {

    private Map<Locale, LocalizedSomeDescription> names = new HashMap<Locale, LocalizedSomeDescription>();

    @OneToMany
    @JoinColumn(name="master_id")
    @MapKeyColumn(name="locale")
    public Map<Locale, LocalizedSomeDescription> getDescriptions() {
        return descriptions;
    }

}

Это приводит к чему-то очень похожему на мой предполагаемый дизайн стола

create table localizedDescriptionss (
    masterClass integer not null,
    id integer not null auto_increment,
    locale varchar(255),
    description varchar(255),
    master_id integer,
    primary key (id)
)

использование mappedBy = "master" во всех подклассах может показаться злоупотреблением наследованием гибернации, но все другие решения будут включать одну строку на подкласс, которая будет нулевой во всех других, что мне кажется очень плохим дизайном таблицы. Мне все еще нужно выяснить, что является «разумным значением по умолчанию» для discriminatorType=DiscriminatorType.INTEGER и нужно ли мне переопределить это значение по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...