Перенос данных SQL из списка Hibernate @OneToMany, который использовал индекс @OrderColumn, но теперь заменяется двусвязным списком - PullRequest
0 голосов
/ 05 июня 2018

У меня есть две схемы БД, обе сгенерированные Hibernate, одна, в которой список элементов внутри Section представляет собой отношение @OneToMany, упорядоченное с использованием @OrderColumn, и другая, в которой порядок элементов Sectionявляется двусвязным списком со ссылками на предыдущий и следующий элементы.Сейчас я пытаюсь перенести данные из исходной БД в новую, используя скрипт на чистом SQL.

Пока что я могу сделать это для одного элемента одного раздела, но не могу обобщить его для всехни элементы, ни все разделы.

(я мог бы написать часть вручную для каждого возможного индекса (в каждом разделе менее 20 элементов), но не для всех разделов (их тысячи)).

Это схемы БД

Схема 1

Аннотации

@Entity
@Table(name = "elements")
public class Element {
  private UUID id;

  ...
}

@Entity
@Table(name = "sections")
public class Section {
  ...

  @OneToMany
    @OrderColumn(name = "order")
    private List<Element> elements = new ArrayList<Element>();

  ...
}

, которая генерирует

CREATE TABLE public.elements
(
  id uuid NOT NULL,
  section_id uuid,
  ...
}

CREATE TABLE public.sections_elements
(
  section_id uuid NOT NULL,
  element_id uuid NOT NULL,
  order integer NOT NULL,
  CONSTRAINTS ...
)


CREATE TABLE public.sections
(
  id uuid NOT NULL,
  ...
)

Схема 2

Аннотации

@Entity
@Table(name = "elements")
public class Element {
  private UUID id;

  @ManyToOne
    private ModelSection section;

  @ManyToOne
    private Element beforeEl;

    @ManyToOne
    private Element afterEl;

  ...

}

@Entity
@Table(name = "sections")
public class Section {
  ...
  (No reference to the elements)
  ...
}

, которая генерирует

CREATE TABLE public.elements
(
  id uuid NOT NULL,
  after_el_id uuid,
  before_el_id uuid,
  section_id uuid,
  ...
)

CREATE TABLE public.sections
(
  id uuid NOT NULL,
  ...
)

Этоскрипт, который обновляет before_el_id и after_el_id первых двух Element с одного Section (заданного жестко id)

-- SET THE ID OF THE BEFORE ELEMENT ID OF THE ELEMENT AT INDEX 0 WITH THAT AT INDEX 1
UPDATE elements els
SET before_el_id = (
    SELECT element_id
    FROM OLD_DB.section_elements sec_els
    JOIN elements els
    ON sec_els.element_id = els.id
    WHERE sec_els.order = 1
    AND sec_els.sec_id = 'ac1031fa-5e4d-1452-815e-51cdc32d002f')
WHERE id = (
  SELECT element_id
  FROM OLD_DB.section_elements sec_els
  JOIN elements els
  ON sec_els.element_id = els.id
  WHERE sec_els.order = 0
  AND sec_els.sec_id = 'ac1031fa-5e4d-1452-815e-51cdc32d002f')
);

-- SET THE ID OF THE AFTER ELEMENT ID OF THE ELEMENT AT INDEX 1 WITH THAT AT INDEX 0
UPDATE elements els
SET before_el_id = (
    SELECT element_id
    FROM OLD_DB.section_elements sec_els
    JOIN elements els
    ON sec_els.element_id = els.id
    WHERE sec_els.order = 1
    AND sec_els.sec_id = 'ac1031fa-5e4d-1452-815e-51cdc32d002f')
WHERE id = (
  SELECT element_id
  FROM OLD_DB.section_elements sec_els
  JOIN elements els
  ON sec_els.element_id = els.id
  WHERE sec_els.order = 0
  AND sec_els.sec_id = 'ac1031fa-5e4d-1452-815e-51cdc32d002f')
);

Вопрос

Есть ли способ обобщить это, по крайней мере, обновить все первые Element s списков для всех Section s?Есть ли способ обобщить это, чтобы обновить все Element из всех Section с?

Если это невозможно с простым SQL (на самом деле я использую PostgreSQL), возможно, есть некоторые инструменты сценариев, которыепоможет?

1 Ответ

0 голосов
/ 06 июня 2018

Я не знаю, есть ли решение для этого, используя только SQL.В итоге я написал короткую программу Node.js, которая подключалась к обеим базам данных и запускала в ней SELECT и UPDATES, используя циклы.

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

Как установить соединение с Postgres через Node.js

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