Как сопоставить список многие-ко-многим в Hibernate с таблицей ссылок

Я хотел бы сопоставить многие-ко-многим в Hibernate с помощью таблицы ссылок. У меня есть два класса, родительский и дочерний, например:

public class Parent{

private List<Child> _children;

//...getters and setters
}

Я использую таблицу ссылок (link_table) с тремя столбцами link_id, parent_id и child_id. База данных - это SQL-сервер, а типы идентификаторов - uniqueidentifier. Итак, я обычно использую guid для полей id.

Как вы можете реализовать это с помощью тега <list />, если это правильный тег для использования? Вы знаете какую-нибудь хорошую документацию для этого?

В настоящее время я получаю исключение ConstraintViolationException, но мне не удалось найти хорошую документацию или примеры этого.

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
7
0
25 250
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

Я использовал только аннотации "многие ко многим", но я думаю, что документация по спящему режиму предлагает примеры на основе XML: текст ссылки

Я делаю это с помощью аннотаций, в частности @ManyToMany и @JoinTable:

Документы Hibernate:

@Entity
public class Employer implements Serializable {
    @ManyToMany(
        targetEntity=org.hibernate.test.metadata.manytomany.Employee.class,
        cascade = {CascadeType.PERSIST, CascadeType.MERGE}
    )
    @JoinTable(
        name = "EMPLOYER_EMPLOYEE",
        joinColumns=@JoinColumn(name = "EMPER_ID"),
        inverseJoinColumns=@JoinColumn(name = "EMPEE_ID")
    )
    public Collection getEmployees() {
        return employees;
    }
}


@Entity
public class Employee implements Serializable {
    @ManyToMany(
        cascade = {CascadeType.PERSIST, CascadeType.MERGE},
        mappedBy = "employees",
        targetEntity = Employer.class
    )
    public Collection getEmployers() {
        return employers;
    }
}

отличный ответ, очень помог

Irina Avram 28.03.2017 18:30
Ответ принят как подходящий

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

При использовании XML вам понадобится такой синтаксис:

 <class name = "Parent">
    ....
    <list name = "children" table = "link_table">
    <key column = "parent_id"/>
    <many-to-many column = "child_id"
        class = "Children"/>
    </list>
    ...
 </class>

<class name = "Child">
...
<list name = "parents" inverse = "true" table = "link_table">
    <key column = "child_id"/>
    <many-to-many column = "parent_id"
        class = "Parent"/>
</list>
...
</class>

Хотя я считаю, что лучше использовать аннотации.

Я считаю, что для этого также требуется индексный столбец.

Brandon 31.12.2008 20:10

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

corsiKa 11.07.2012 09:15

«столбец индекса» сильно отличается от индекса базы данных в этом контексте.

araqnid 23.11.2012 18:46

@Brandon, почему Hibernate требует дополнительного столбца индекса?

zygimantus 31.05.2017 22:12

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

Эта объединенная таблица может содержать PK или может содержать некоторые дополнительные поля без PK. См. Этот блог для точной реализации Глянь сюда

И в соответствии с вашим примером вам нужен дополнительный PK в таблице, поэтому вы объявляете новую таблицу ParentChildren и объявляете свой первичный ключ как linkId. Я показываю только аннотированный класс parentchildren, так как на аннотации для сопоставления многих ко многим в родительском и дочернем классе можно ссылаться в сообщении выше.

@Entity
@Table(name = "parent_children")
public class ParentChildren{
    @Id @GeneratedValue
    private long linkId;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "parent_id") 
    private Parent parent;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "children_id) 
    private Children children;

    // additional fields if you want
    private boolean activated;

    //getters and setters
    }
}

Таким образом, будет создана таблица сопоставления, в которой linkId является первичным ключом, а parent_id и children_id - внешним ключом. Просто поясните, почему вам нужен link_id отдельно в качестве первичного ключа и как вы собираетесь его использовать.

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