Как лучше всего делиться OneToMany с другими? - PullRequest
0 голосов
/ 03 мая 2018

Допустим, у меня таблица выглядит следующим образом.

K VARCHAR PK
V VARCHAR

В одной таблице хранятся записи ключей и значений.

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

Объект A имеет несколько свойств, а объект B может иметь несколько свойств.

@Entity
class Property {

    String key;
    String value;
}

Каков наилучший способ передачи сущности Property другим сущностям?

@Entity
class Some {

    @OneToMany
    private List<...Property> properties;
}

@Entity
class SomeOther {

    @OneToMany
    private List<...Property> properties;
}

Я планирую использовать наследование.

@Entity
@Inheritance
class Property {
}

И я знаю, что могу расширить его.

@Entity
@DiscriminatorValue("SomeOther")
class SomeProperty extends Property {
}

@Entity
@DiscriminatorValue("SomeOther")
class SomeOtherProperty extends Property {
}

Теперь, как должны выглядеть мои столы?

Должен ли я создать SOME_PROPERTY таблицу?

Или я должен добавить SOME_ID в PROPERTY таблицу?

1 Ответ

0 голосов
/ 03 мая 2018

Лично я бы постарался сделать все просто.

Текущее отображение, т. Е .:

@Entity
class Some {

    @OneToMany
    private List<Property> properties;
}

создает таблицу соединения, которая связывает строки в SOME и PROPERTY. Вы получите почти то же самое с InheritanceType.JOINED.

Если вы слегка измените свое отображение:

@Entity
class Some {

    @OneToMany
    @JoinColumn
    private List<Property> properties;
}

вы получите внешний ключ в PROPERTY, указывающий на SOME (и повторное использование этого сопоставления для SomeOther приведет к еще одному внешнему ключу). Вы получите почти то же самое с InheritanceType.SINGLE_TABLE.

Использование наследования здесь только усложнит ситуацию. Я бы выбрал один из вариантов выше или использовал бы еще более простое сопоставление:

@Entity
public class Some {

    @ElementCollection
    @MapKeyColumn(name = "K")
    @Column(name = "V")
    @CollectionTable(name = "PROPERTY", joinColumns = @JoinColumn(name = "some_id"))
    private Map<String, String> properties;
}

Выше представлены свойства как Map<String, String>, которые действительно являются такими, какие они есть. Единственным недостатком является то, что при повторном использовании этого сопоставления (изменение только имени столбца соединения, например, some_other_id) у вашего поставщика JPA могут возникнуть проблемы при создании схемы. Конечно, вы можете решить хранить свойства для разных сущностей отдельно, и в этом случае вы можете изменить имя таблицы сбора (тогда вы получите эквивалент Inheritance.TABLE_PER_CLASS).

Кстати, я не думаю, что K имеет смысл быть первичным ключом, предполагая, что ключи будут повторяться для разных экземпляров Some. Если вы выберете одно из решений с использованием @OneToMany, я бы рекомендовал добавить суррогатный ключ (поле @Id @GeneratedValue Long id) к объекту Property.

...