ManyToMany отношения и сохранения объектов - PullRequest
0 голосов
/ 06 июня 2018

У меня есть отношения manyToMany между двумя объектами: team и person .Я создал метод, чтобы добавить человека в команду.

Если я создаю этот метод только в одном сервисе (команде), могу ли я добавить людей в команды и команды к человеку, если у меня есть отношения manyToMany, или мне нужно создать один и тот же метод в личной службе?

Это мой метод:

public void addPersonsToTeams(Long teamId, Long personId) {
        Assert.notNull(personId, "Object can't be null!");
        Assert.notNull(teamId, "Object can't be null!");
        try {
            Person person = personRepository.getOne(personId);
            Team team = teamRepository.getOne(teamId);
            person.getTeams().add(team);
            personRepository.save(person);
        } catch (Exception e) {
            throw new CreateEntityException();
        }

    }

1 Ответ

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

РЕДАКТИРОВАТЬ Из https://stackoverflow.com/users/2224047/nikolay-shevchenko комментарий Я понимаю, что платформа ORM может решить проблему синхронизации «многие ко многим» сама по себе.Я также предполагаю, что он справится с проблемами блокировки.В любом случае, я позволю свой предыдущий ответ, так как считаю, что это все еще хорошая проблема проектирования.

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

Если говорить конкретно, это неправильно imo

Team team = teamRepository.getOne(teamId);
person.getTeams().add(team);
personRepository.save(person);

Поскольку (по крайней мере, в коде) кажется, что вы храните копию командного объекта внутри человека в вашем хранилище.Но объект команды может быть изменен вне этого контекста.Например, команда может иметь нового человека.Тогда ваш личный объект будет содержать командный объект, не синхронизированный с тем, который хранится в командном хранилище.В итоге вы получаете 2 разных командных объекта, которые хранятся в разных местах.Опять же, если ваш ORM-фреймворк решает это для вас, то вы, вероятно, хороши, но я думаю, что вам все же стоит подумать о редизайне своего кода и не допускать, чтобы ваш ORM решал такую ​​дилемму.

Я бы вместо этого написал нечто подобное

if(teamRepository.contains(teamId)){
    person.getTeamIds().add(teamId);
    personRepository.save(person);
}

Теперь, чтобы синхронизировать командный объект, вы можете использовать какое-то доменное событие.Прослушайте это в групповой службе и выполните противоположную операцию внутри групповой службы.Но если эта операция синхронизации выполняется в другой транзакции, которая, вероятно, будет иметь место, то это означает, что в какой-то момент ваша БД не согласована.Это может быть проблемой или не для вас.Кроме того, что произойдет, если ваш бэкэнд выйдет из строя между операцией синхронизации и т. Д.Может быть, они являются частью одного и того же сервиса или даже агрегата, и тогда вы можете обновить их одновременно?

Это большой вопрос проектирования, и я предлагаю взглянуть на то, что такое агрегат, и прочитать о доменный дизайн .

Надеюсь, это поможет:)

...