Дополнительные столбцы в Spring Data JPA Relationship с минимальными изменениями

Мне нужно внести изменения в модель проекта. В настоящее время у нас есть два класса с двунаправленными отношениями «многие ко многим» (что подразумевается в таблице отношений), и теперь нам нужно добавить дополнительную информацию в отношения.

Мой вопрос: единственный способ сделать это - создать класс для отношения (например, создать его с тем же именем, что и таблица отношений, которая уже существует)?

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

Два класса, о которых я говорю, чтобы было понятнее:

@Entity
public class Serie extends AbstractEntity {
   @ManyToMany
   private List<Disciplina> disciplinas;
}

@Entity
public class Disciplina extends AbstractEntity {
   @ManyToMany(mappedBy = "disciplinas")
   private List<Serie> series;
}

Почему? Вам не нужно раскрывать реализацию. Вы по-прежнему можете вернуть List<Disciplina> и List<Serie>, обработав модель в памяти и не раскрывая отношения объекту Join.

Alan Hay 08.05.2018 11:07

Вы имеете в виду добавить столбец в таблицу serie_disciplina и получить к нему доступ через модель? Если да, то есть разные способы, например, введение карты в модель.

garfield 08.05.2018 11:43

@garfield, таблица уже существует (спящий режим делает это по умолчанию, когда мы впервые установили связь). Мне нужно добавить больше информации об отношениях.

Filipe Mendes 09.05.2018 02:11

@AlanHay, как я могу получить доступ к новой информации, используя текущую связь? Мне нужно добавить больше информации в таблицу serie_disciplinas и использовать ее в коде. Но для создания нового класса (например, SerieDisciplinas) потребуется много изменений в коде и запросах. Мой вопрос касается того, есть ли другой способ сделать это без стольких изменений.

Filipe Mendes 09.05.2018 02:15

Я забыл сказать, что запросы выполняются на HQL, что подразумевает, что они выполняются с использованием модели java, а не таблиц.

Filipe Mendes 09.05.2018 02:17

@Filipe Mendes, было бы полезно узнать, какая дополнительная информация включена в таблицу соединений. Одно из решений состоит в том, чтобы сохранить исходные сущности и сопоставить объединяемую таблицу с новой сущностью, используя отношения ManyToOne с исходными сущностями, а затем заменить ManyToMany исходными сущностями на OneToMany с сущностью, сопоставляющей таблицу объединения.

garfield 09.05.2018 09:09
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
287
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как рекомендовано в комментариях, вам нужна сущность соединения, но не нужно открывать ее для клиентов вашей модели домена: выполнив что-то вроде приведенного ниже, вам нужно будет только изменить любой клиентский код, который напрямую изменяет коллекции, чтобы вызвать addXXX / removeXXX методы. Ни один клиентский код не знает только об объекте Join. Поэтому изменения в вашем Java-коде должны быть незначительными.

Что касается запросов, вам, очевидно, нужно будет изменить их по мере необходимости.

Серия

@Entity
public class Serie extends AbstractEntity {

    @OneToMany(mappedBy = "serie")
    private List<SerieDisciplina> serieDisciplinas;

    public List<Disciplina> getDisciplinas(){
            //disciplinas extracted from serieDisciplinas 
            return Collections.unmodifiableList(...); 
    }

    public void addDisciplina(Disciplina disciplina){
        SerieDisciplina sd = new SerieDisciplina();
        sd.stSerie(this);
        sd.setDisciplina(disciplina);

        serieDesciplinas.add(sd);   
    }
}

Дисциплина

@Entity
public class Disciplina extends AbstractEntity {

    @ManyToMany(mappedBy = "disciplina")
    private List<SerieDisciplina> serieDisciplinas;

    public List<Serie> getSeries(){
        //series extracted from serieDisciplinas
        return Collections.unmodifiableList(...); 
    }

    public void addSerie(Serie serie){
        SerieDisciplina sd = new SerieDisciplina();
        sd.stSerie(Serie);
        sd.setDisciplina(this);

        serieDesciplinas.add(sd);
    }
}

Присоединиться к Entity

@Entity 
public class SerieDisciplina{
    @ManyToOne
    private Serie serie;

    @ManyToOne
    private Disciplina disciplina;

    //fields for the additional data about the relationship

    //getters and setters
}

Документы Hibernate предлагают в первую очередь избегать @ManyToMany, чтобы избежать таких проблем. См. Обсуждение по адресу: Рекомендации по Hibernate: избегайте отношений "многие-ко-многим" и "экзотических" отношений

Другие вопросы по теме