Сохранить карту с enum в качестве ключа и список объектов в качестве значения - PullRequest
1 голос
/ 23 мая 2019

Я борюсь с сохранением карты.Прежде всего, вот мой дизайн базы данных: enter image description here У меня есть один боковой загрузчик, который может иметь до 5 различных размеров контейнеров.ContainerSize определяется как перечисление.Для каждого размера контейнера есть несколько записей масштаба.Так что это отношение от 1 до 5 к n .

В настоящее время я представляю этот дизайн со следующими объектами:

@Entity
@Table(name = "sideloader")
public class SideloaderEntity {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    @Column(name = "currency")
    private Currency currency;

    // TODO
    private Map<ContainerSize, SideloaderContainersizeEntity> scalesPerContainerSize;

@Entity
@Table(name = "sideloader_containersize")
public class SideloaderContainersizeEntity {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    //TODO
    private List<SideloaderScaleEntity> scales;

@Entity
@Table(name = "sideloader_containersize_scale")
public class SideloaderScaleEntity {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long scaleId;

    @Column(name = "upper_bound_distance_km")
    private int upperBoundDistanceKm;

    ...

Теперь я застрял,Я не уверен, смогу ли я даже сопоставить это с моим существующим макетом базы данных.И я не знаю, какие аннотации мне нужно использовать.Я уже читал некоторые статьи о том, «как сохранить карту», ​​но эти статьи всегда описывают отображение без существующего макета базы данных.

Можете ли вы помочь мне, пожалуйста?

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Я бы постарался добиться вашего результата в три этапа:

  1. Попробуйте отобразить отношения между SideloaderEntity и SideloaderContainersizeEntity, используя List, и на мгновение пропустите отношения между SideloaderContainersizeEntity и SideloaderScaleEntity. Для этого вполне достаточно заменить private Map<ContainerSize, SideloaderContainersizeEntity> scalesPerContainerSize; на @OneToMany(mappedBy = "sideloaderEntity") private List<SideloaderContainersizeEntity> sideloaderContainersizeEntities;, где sideloaderEntity - это поле @ManyToOne private SideloaderEntity sideloaderEntity вашего SideloaderContainersizeEntity.
  2. Попробуйте заменить List на Map: замените private List<SideloaderContainersizeEntity> sideloaderContainersizeEntities; на @MapKey(name = "containerSize") private Map<ContainerSize, SideloaderContainersizeEntity> scalesPerContainerSize;, где containerSize - это поле private ContainerSize containerSize вашего SideloaderContainersizeEntity.
  3. Добавьте отношение между SideloaderContainersizeEntity и SideloaderScaleEntity как List.
0 голосов
/ 23 мая 2019

С помощью коллеги и поста @ Smutje я нашел следующее решение:

@Entity
@Table(name = "sideloader")
public class SideloaderEntity {

    @Column(name = "currency")
    private Currency currency;

    @OneToMany(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "sideloader_id", referencedColumnName = "id")
    @MapKey(name = "containerSize")
    private Map<ContainerSize, SideloaderContainersizeEntity> scalesPerContainerSize;

@Entity
@Table(name = "sideloader_containersize")
public class SideloaderContainersizeEntity {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    @Enumerated(EnumType.STRING)
    @Column(name = "container_size")
    private ContainerSize containerSize;

    @OneToMany(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "sideloader_containersize_id", referencedColumnName = "id")
    private List<SideloaderScaleEntity> scales;

@Entity
@Table(name = "sideloader_containersize_scale")
public class SideloaderScaleEntity {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long scaleId;

    @Column(name = "upper_bound_distance_km")
    private int upperBoundDistanceKm;

    ...

Я протестировал, чтобы сохранить его с помощью следующего кода, и, похоже, он работает:

@Test
void foo() {

    SideloaderPriceComponent sideloader = new SideloaderPriceComponent();

    SideloaderScaleEntity scale = new SideloaderScaleEntity();
    scale.setUpperBoundDistanceKm(10);

    SideloaderContainersizeEntity containersize = new SideloaderContainersizeEntity();
    containersize.setContainerSize(ContainerSize.FORTY);
    containersize.setScales(Collections.singletonList(scale));

    sideloader.setScalesPerContainerSize(Collections.singletonMap(ContainerSize.FORTY, containersize));

    em.persist(sideloader);
    em.flush();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...