Разница между использованием @OneToMany и @ManyToMany
у меня возникли некоторые проблемы с пониманием разницы между @OneToMany
и @ManyToMany
. Когда я использую @OneToMany
по умолчанию создается объединяемая таблица, и если вы добавите атрибут mappedBy, у вас будет двунаправленная связь между двумя сущностями.
у меня есть Question
это может принадлежать многим Categories
и один Category
может принадлежать многим Questions
. Я не понимаю, если я должен использовать @ManyToMany
или @OneToMany
потому что для меня это кажется точно таким же, но это, вероятно, не так.
может кто-нибудь объяснить это?
3 ответов
Ну, разница в дизайне, вы пытаетесь отразить с помощью объектов.
в вашем случае, каждый Question
может быть назначено несколько Categories
- так это знак @*ToMany
отношения. Теперь вы должны решить, если:
- каждого
Category
может быть только одинQuestion
присваивается ему (это приведет к уникальный ограничение, которое означает, что никакая другая категория не может ссылаться на тот же вопрос) - это будет@OneToMany
отношения, - каждого
Category
может иметь несколькоQuestions
назначенный ему (вCategory
"таблица") - это будет@ManyToMany
отношения.
@OneToMany (Вопрос -> Категория)
это отношение может быть представлено таблицей join, только если вы явно определяете это, используя @JoinTable
это однонаправленный отношения, в которых владеющая сторона является "одной" стороной (это означает что в Question
сущности, у вас есть коллекция Categories
, но в Categories
у вас нет никакой ссылки на Question
).
если вы думаете об этом, кажется вполне разумным, что используется таблица join. Нет другого способа, которым СУБД могла бы сохранить соединение между одной строкой в Question
таблица с несколькими строками в Categories
таблица.
однако, если вы хотите смоделировать двунаправленное отношение, вам нужно указать, что Category
('много' сторона) является ведомой стороне. В этом случае СУБД может создать столбец соединения с внешним ключом в Category
таблица, потому что каждый Category
строка может быть связана только с одним Question
.
таким образом, у вас нет никакой таблицы соединений, кроме простых внешних ключей (тем не менее, как указано в начале, вы можете заставить создать таблицу соединений с помощью @JoinTable
).
@ManyToMany
эта связь должна быть представлена в таблице. Он в основном работает очень похоже на однонаправленный @OneToMany
отношения, но в этом случае у вас может быть несколько строк из Question
соединено с несколькими строками из Categories
.
@ManyToMany отношения имеют взаимно ссылочные внешние ключи с обеих сторон отношений. Иногда эта связь опосредуется соседней таблицей.
@OneToMany отношения имеют внешний ключ на стороне "один", а не на стороне" много". В отношениях @OneToMany один объект является "родительским", а другой - "дочерним". Родитель контролирует существование ребенка.
помните, что двунаправленное отношение @ManyToMany не обязательно должно быть симметрично!
в вашем случае вопросов и категорий, вы должны использовать @ManyToMany отношения. @ManyToMany в основном означает ,что" вопрос может принадлежать ко многим категориям одновременно "и"категория может содержать много вопросов одновременно". Для хранения сопоставлений будет автоматически создана новая таблица. Ваш код будет выглядеть так:
@Entity
public class Question implements Serializable {
...
@ManyToMany
private List<Category> categories;
...
}
@Entity
public class Category implements Serializable {
...
@ManyToMany
private List<Question> questions;
...
}
Если вы используете отношение @OneToMany для своих вопросов и категорий (скажем, категория С одной стороны и вопросы на другое), это означает ,что" вопрос может принадлежать только к одной категории "и"категория может содержать много вопросов одновременно". Для хранения сопоставления не требуется новая таблица. Вместо этого новое поле будет автоматически создано во многих сторонах для записи идентификатора одной стороны. Ваш код будет выглядеть так:
@Entity
public class Question implements Serializable {
...
@ManyToOne
private Category theCategory;
...
}
@Entity
public class Category implements Serializable {
...
@OneToMany(mappedBy="theCategory")
private List<Question> questions;
...
}