Порядок каскада в спящем режиме, генерация идентификаторов и двунаправленные отношения - PullRequest
0 голосов
/ 11 марта 2019

Рассмотрим три следующих объекта с соответствующими отношениями:

public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected UUID id;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Event> events = new HashSet<>();

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Entry> entries = new HashSet<>();
}
public class Event {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected UUID id;

    @ManyToOne(fetch= FetchType.LAZY)
    @JoinColumn(name="project_id")
    private Project project;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "event")
    protected Set<Entry> entries = new HashSet<>();
}
public class Entry {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected UUID id;

    @ManyToOne(fetch= FetchType.LAZY)
    @JoinColumn(name="project_id")
    private Project project;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="event_id", nullable=false)
    protected Event event;
}

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

Основными проблемами, которые я обнаружил, были:

  • (1) Поскольку Генерация идентификатора находится в базе данных , я не могу добавить их всев проект, а затем сохраните записи.Чтобы синхронизировать двунаправленные отношения, мне нужно сначала сохранить их, а затем добавить или сохранить проект и каскадировать записи после добавления.Особенно, когда у меня есть коллекция сущностей, которые уже сохранены, и сущности, у которых еще нет PK, мне нужно очистить набор всей коллекции новой или сохранить сущности перед их добавлением.

  • (2) Порядок каскадирования отсутствует : При попытке сохранить проект и каскадировании записей дочерние объекты не могут иметь взаимозависимых отношений.Например, что если он попытается сохранить записи до сохранения событий?Я не смог найти никакой опции для установки каскадного порядка.

  • (3) Двунаправленное отношение между входом-событием также необходимо синхронизировать,Однако некоторые события добавляются недавно, в то время как другие уже существуют и сохраняются, а для вновь добавленных нам необходимо следить за (1).

Вопрос в том, как это сделать.лучше всего?

Я мог бы сохранять сущности во время создания, но тогда у меня была бы одна транзакция при каждом создании.В качестве альтернативы я мог бы сохранить их все в объекте результата и в конце сохранить их, а затем добавить их в проект и сохранить проект.Тем не менее, оба эти варианта мало используют опцию каскадирования и являются довольно сложными в том смысле, что они добавляют временные зависимости.(сначала сохраните X, затем Y, затем Z) * ​​1032 *


Обновление: код, как я сейчас добавляю сущности и сохраняю их в проект

В проекте есть вспомогательные методы, которые устанавливают толькоЗаписи (может установить двунаправленное отношение, но Project не может быть нулевым при создании записи / события):

public void addEntries(Collection<Entry> entries){
        this.entries.addAll(entries);
    }


    public void addEvents(Collection<Event> events){
        this.events.addAll(events);
    }


    public void addEntry(Entry entry){
        this.entries.add(entry);
    }


    public void addEvent(Event event){
        this.events.add(event);
    }

В настоящее время я сохраняю события при создании и записи после функции моделирования.Проект всегда сохраняется в самом конце после всех операций.

    public ADEvent createADEvent(Round round) {
        ADEvent event = new ADEvent(round);
        event = saveDB ? eventRepository.save(event) : event;
        round.getProject().addEvent(event);
        return event;
    }

    public void saveEntries(Project project, Collection<Entry> entries) {
        if (saveDB) entries = entries.stream().map(entryRepository::save).collect(Collectors.toList());
        project.addEntries(entries);
    }

    public Project saveProject(Project project) {
        return saveDB ? projectRepository.save(project) : project;
    }

Обновления выполняются таким же образом, просто я очищаю всю коллекцию в проекте перед запуском метода симуляции.(и удалить все события симуляции)

1 Ответ

0 голосов
/ 12 марта 2019

Я бы не спасал каждую сущность отдельно. Проблемы могут не возникнуть при сохранении вместе с проектом. Каскадирование определено правильно, я смог добавить их все и сохранить project. Просто убедитесь, что установлены обе стороны отношения

    Project p = new Project();
    Entry ntry = new Entry();
    Event event = new Event();

    p.getEntries().add(ntry);
    ntry.setProject(p);// set also other side of relation
    ntry.setEvent(event);

    p.getEvents().add(event);
    event.setProject(p);// set also other side of relation
    event.getEntries().add(ntry);

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