Довольно детский вопрос, но я запутался. Использую Hibernate. Он же и создает таблицы. Есть сущность пользователь, есть сущность сессия. У одного пользователя может быть много сессий.
public class Session {
@Id
@Column(name = "id")
@GeneratedValue()
private long id;
@Column(name = "token")
private String token;
@ManyToOne(fetch = FetchType.LAZY)
private User user;
}
public class User {
@Id
@Column(name = "id")
@GeneratedValue
private long id;
@Column(name = "name", nullable = false)
private String name;
@OneToMany(fetch = FetchType.LAZY)
private List<Session> sessions;
}
Собственно что не так. Я хочу чтобы была сгенерирована такая структура в БД:
Users(id, name)
Sessions(id, token, userId)
В целом то оно так и вышло. И даже заполняется правильно. Но дополнительно генерируется ещё одна таблица, которая остается пустой. При тестовом созаднии и входе пользователя:
Таблица Users
Таблица Sessions
Таблица UserSessions
Может мне кто нибудь разжует, что к чему? Я в принципе понимаю, зачем вообще создавать такую таблицу. У одного пользователя может быть (на самом деле нет, но гибернейт же этого не знает) теоретически несколько сессий, и в то же время одна сессия может быть у нескольких пользователей, аля экономия места + целостность БД. Но почему она тогда не заполняется?
Чтобы разобраться интересны оба случая, как заставить её (таблицу UserSessions) заполняться и убрать этот userId из таблицы Sessions; так и наоборот, как убрать таблицу UserSessions, оставив userId. И как так получилось у меня что создается не используемая таблица?
Всё просто. Таким образом у Вас получились две независимые друг от друга односторонних связи.
Одна-ко-многим (user->sessions) совершенно естественно создаёт join-таблицу.
Чтобы создать обратную сторону двусторонней связи следует делать так:
public class User {
...
@OneToMany(mappedBy = "user")
private List<Session> sessions;
....
}
Так JPA видит, что эта связь - это обратная сторона двусторонней связи. А прямая задана в Session атрибутом user.
При этом никаких лишних join-таблиц не будет, ибо теперь известно, что связь держится через session.
Разобрался. Нужно было залезть в документацию (на всяких обучающих сайтах толкового мало). Вопрос удалять не буду, вдруг пригодится кому нибудь.
В общем есть три ситуации.
Описано ManyToOne. Тогда создаётся только внешний ключ. Никаких таблиц дополнительных не создается.
Описано OneToMany. Делается через дополнительную таблицу.
Описано OneToMany и ManyToOne. При этом снова работает только через внешний ключ. Но! У OneToMany обязательно должно быть прописано MapedBy, иначе сработает случай выше и будет создана дополнительная таблица.
Всё же вопрос, интересен... А почему так? Чем так принципиально отличается OneToMany от ManyToOne, что без таблицы никак? На который я сам логически и нашел ответ ) Опять же, может кому то полезно будет. При ManyToOne мы в таблице где может быть "много" объектов описываем свойство ссылающиеся на "один" объект. Никакой дополнительной таблицы не нужно. Но если мы описываем OneToMany, то получается в объекте "один" должен быть список других объектов. А этот список и выражается в этой самой дополнительной таблице. Вот так.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Подскажите пожалуйста как составить regexp для такой строки /utils/add/message? таких /действие может быть сколько угодно