powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate @OneToMany @ManyToOne
34 сообщений из 34, показаны все 2 страниц
Hibernate @OneToMany @ManyToOne
    #37647369
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Помогите пожалуйста.

Есть три сущности: Users, Books, Comments
Users @OneToMany Comments
Books @OneToMany Comments
Comments @ManyToOne Users, Books

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@Entity
@Table(name = "Users")
public class Users implements Serializable{
   @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long userId;
   
   @OneToMany(targetEntity = Comments.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   private List<Comments> commentsForUser;



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@Entity
@Table(name ="Books")
public class Books implements Serializable {
  @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "book_id")
    private Long bookId;
  
    @OneToMany(targetEntity = Comments.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Comments> commentsForBook;



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
@Entity
@Table(name ="Comments")
public class Comments implements Serializable{
   @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "comment_id")
    private Long commentId;
   
   @ManyToOne(targetEntity = Users.class, cascade = {CascadeType.REFRESH}, fetch =FetchType.LAZY)
   @JoinColumn(name = "user_id")
   private Users user;
   
    @ManyToOne(targetEntity = Books.class, cascade = {CascadeType.REFRESH}, fetch =FetchType.LAZY)
    @JoinColumn(name = "book_id")
    private Books book;



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
public class Main {

    public static void main(String[] args) {
    
        Session session = HibernateUtil.getSessionFactory().openSession();
       
        session.beginTransaction();
        Books book = new Books();
        book.setBook("Книга краба");
        book.setAutor("Краб");
        book.setDescription("Книга краба, классная");
        book.setImage("Ссылка на картинку для книги");
        book.setFile("Ссылка на файл для книги");
        book.setNumberComments(0);
        book.setNumberDownloads(0);
        book.setYearToPublication(2009);
        session.save(book);
        session.getTransaction().commit();
        
        session.beginTransaction();
        Users user = new Users();
        user.setLogin("krab");
        user.setPassword("qwerty");
        user.setName("Андрей");
        user.setSName("Коваленко");
        user.setOnLibrary(true);
        user.setCommentsNumber(1);
        user.setRegisterDate(new Date(System.currentTimeMillis()));
        session.save(user);
        session.getTransaction().commit();
        
        
        session.beginTransaction();
        Comments comment = new Comments();
        comment.setTextComment("Классная книга");
        comment.setDateOfComment(new Date(System.currentTimeMillis()));
        comment.setUser(user);
        comment.setBook(book);
        session.save(comment);
        session.getTransaction().commit();
        
        session.close();
        
       System.out.println(user.getCommentsForUser());
       System.out.println(book.getCommentsForBook());
        
        
    }
}



В консоль выводит:
Код: plsql
1.
2.
3.
4.
5.
Hibernate: insert into Books (autor, book, description, file, image, numberComments, number_Downloads, year_to_publication) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into Users (comments_Number, login, name, on_Library, password, register_Date, s_Name) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into Comments (book_id, date_of_comment, text_comment, user_id) values (?, ?, ?, ?)
null
null



По идее как я понимаю null не должно выводить. Подскажи, может аннотации @OneToMany и @ManyToOne не правильно написал?


Заранее спасибо.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37647465
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это все должно выглядеть примерно вот так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@Entity
@Table(name = "Users")
public class Users implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long userId;
   
    @OneToMany(mappedBy="user", cascade = CascadeType.ALL)
    private List<Comments> commentsForUser;


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@Entity
@Table(name ="Books")
public class Books implements Serializable {
  @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "book_id")
    private Long bookId;
  
    @OneToMany(mappedBy="book", cascade = CascadeType.ALL)
    private List<Comments> commentsForBook;


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
@Entity
@Table(name ="Comments")
public class Comments implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "comment_id")
    private Long commentId;
   
    @ManyToOne(cascade = {CascadeType.REFRESH})
    @JoinColumn(name = "user_id")
    private Users user;
   
    @ManyToOne(cascade = {CascadeType.REFRESH})
    @JoinColumn(name = "book_id")
    private Books book;
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37647560
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, поменял, все-равно не работает, также выводит ссылки null.
Может в чем-то другом проблема?

Заранее спасибо.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37647618
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте cascade = {CascadeType.REFRESH} поменять на cascade = {CascadeType.ALL}
НО!!! Возьмите себе за правило, что когда имеете дело с двунаправленными отношениями, то явно обновляйте их с обоих сторон. Т.е. вместо
Код: java
1.
comment.setUser(user);

надо писать
Код: java
1.
2.
comment.setUser(user);
user.getComments().add(comment);
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37647653
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторПопробуйте cascade = {CascadeType.REFRESH} поменять на cascade = {CascadeType.ALL}
Поменял. Также выдает null

Код: java
1.
2.
comment.setUser(user);
user.getComments().add(comment);



После этого конечно поля заполнены, но это ручная работа.Не понимаю тогда смысла данных аннотаций. Я думал что поля должны заполнятся автоматически. Хотя конечно тут ключевое слово "думал" :)
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37647756
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Скорее всего, это связано с тем, что вы каждое действие делаете в отдельной транзакции.
Попробуйте сделать все в одной транзакции, а для записи изменений в базу используйте session.flush().
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37647976
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Это то есть примерно так?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
    public static void main(String[] args) {
    
        Session session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();

        Books book = new Books();
        book.setBook("Книга краба");
        ...
        session.flush();
        
        Users user = new Users();
        user.setLogin("krab");
        ...
       session.flush();
      
       Comments comment = new Comments();
       comment.setTextComment("Классная книга");
       ...
        session.flush();

        session.save(book);
        session.save(user);
        session.save(comment);

        session.getTransaction().commit();
        
        session.close();
        
       System.out.println(user.getCommentsForUser());
       System.out.println(book.getCommentsForBook());
        
        
    }

        



Все-равно выводит нулл)
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37647977
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хотя конечно если явно обновлять, то все ок
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648057
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krab,

Убери все лишние поля из примера и обьясни БЛ по связям. Для какой задачи они нужны.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648086
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krab,

Попробуйте оставить один flush в самом конце.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648294
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,

Есть 3 таблицы. Users, Books, Comments

Users имеет много комментариев, то есть связь один ко многим:

Код: java
1.
2.
    @OneToMany(mappedBy="user", cascade = CascadeType.ALL)
       private List<Comments> commentsForUser;



Books имеет много комментариев, то есть связь один ко многим:

Код: java
1.
2.
    @OneToMany(mappedBy="book", cascade = CascadeType.ALL)
       private List<Comments> commentsForBook;



Comments соответственно:

Код: java
1.
2.
3.
4.
5.
6.
7.
    @ManyToOne(cascade = {CascadeType.ALL})
        @JoinColumn(name = "user_id")
        private Users user;
       
        @ManyToOne(cascade = {CascadeType.ALL})
        @JoinColumn(name = "book_id")
        private Books book;



Хочу чтоб при заполнении полей авторprivate Books book; и авторprivate Users user;
автоматически добавлялись комментарии в списки авторprivate List<Comments> commentsForUser; и
авторprivate List<Comments> commentsForBook;
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648297
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonidv,

Не помогло)
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648312
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krabComments соответственно:
доп.вопрос - зачем в комментарии тебе доп.ссылки на родителей?
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648324
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krab,
вопрос снимается. Позже в коде посмотрю - отвечу.

Общий случай тебе svenom сказал - вручную и небольшая автоматизация при inverse = True 2 метода объединить в один.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648353
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krab,
ну, давай попробуем....
По логике не вяжется.
- Зачем нужны о одних комментариев - 2 родителя?
- Что за комментарии у Books?
IMHO неправильные ассоциации в модели предметной области.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648361
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В объектной модели все в порядке. Каждый комментарий связан с прокомментированной книгой и с пользователем, который его оставил. Логично, что в какой-то момент мы можем захотеть посмотреть все комментарии к данной книге или все комментарии данного пользователя. Логично и разумно.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648379
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svenomВ объектной модели все в порядке. Каждый комментарий связан с прокомментированной книгой и с пользователем, который его оставил. Логично, что в какой-то момент мы можем захотеть посмотреть все комментарии к данной книге или все комментарии данного пользователя. Логично и разумно.
я не спорю, я предлагаю ВРЕМЕННО убрать ЧТО МЫ ХОТИМ СМОТРЕТЬ и отработать персистентность.
Т.е. легко и просто сохранять в БД
Или ИДТИ ОТ БД а не от ОРМ.
От ОРМ можно пойти через 15 минут.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648401
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krab,
предметная область.
От неё зависит модель.
- что является ПРЕДМЕТОМ учёта?
Вариант:
Книги много комментариев + пользователь
или
Код: java
1.
2.
Книги Один ко многим --> комментарии
Комментарий 1 к 1 --> пользователь



______________________________________________
"Сделай настолько просто, насколько это возможно, но не проще". © А. Эйнштейн.
AutoPOI.ru — ГИС-технологии для Oracle
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648755
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,
Я ценю Вашу помощь, но немного не понимаю Вас.

Предметная область вроде и так должна быть ясна. Обычная библиотека с книгами.
Каждая книга может иметь множество комментариев. Также и пользователь может иметь множество комментариев.
Книги один ко многим -> Комментарии
Пользователь один ко многим -> Комментарии
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648767
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krabPetro123,
Предметная область вроде и так должна быть ясна. Обычная библиотека с книгами.

===== нет, если главный - Комментатор или Писатель, то модель будет другая.
Предположим что - Библиотека - OK

Каждая книга может иметь множество комментариев. Также и пользователь может иметь множество комментариев.

нет.
Пользователь имеет множество только опосредствованно, по ссылке через другой объект.
Т.е. сам по себе, без книг, он имеет комментарии только по ДОП.запросу _аналитическому_ в БД.

Т.е. он имеет множество комментарие, но только через книги которые комментирует.

Ведь комментарий без книги невозможен? (NOT NULL)
?
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648771
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пы сы - отформатировал
krabPetro123,
Предметная область вроде и так должна быть ясна. Обычная библиотека с книгами.

===== нет, если главный - Комментатор или Писатель, то модель будет другая.
Предположим что - Библиотека - OK

Каждая книга может иметь множество комментариев. Также и пользователь может иметь множество комментариев.

нет.
Пользователь имеет множество только опосредствованно, по ссылке через другой объект.
Т.е. сам по себе, без книг, он имеет комментарии только по ДОП.запросу _аналитическому_ в БД.

Т.е. он имеет множество комментарие, но только через книги которые комментирует.

Ведь комментарий без книги невозможен? (NOT NULL)
?
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648773
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krab,
не забывайте про БД и 3 степени нормализации.
Покажите 3 таблички с 2-мя заполненными строками. Как бы вы хотели видеть в БД.
У нас ООБД пока не существует.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648784
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,

авторВедь комментарий без книги невозможен?
Да, также и книгу нельзя посмотреть без входа в библиотеку.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648808
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krabPetro123,
авторВедь комментарий без книги невозможен?
Да, также и книгу нельзя посмотреть без входа в библиотеку.
класса библиотеки у нас нету :)

Держи вариант:
ВИ - User - справочник а не встроенный класс в Коммент
Применяют когда выделенный класс User достаточно большой и его выбирают на клиенте из комбобокса.
====================
Книги ----много ко много -------Пользователь
1 Книга - много комментариев (1 к *)
Комментарий - справочникПользователь (FK)

авторКнига
код Название1 ВойнаИмир2 Мурзилка

авторКоммент
код кодКниги FKUser Текст23 2 34 Плохая45 2 34 Супер

авторUser
код FIO34 Петров34 Сидоров
вот эту схему БД пробуй промаппить на ОРМ.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648825
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, каскад на удаление только с книги на коммент. База юзверей не удаляется.
Получится маппинг с минимумом полей в классах напиши.
Удачи!
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648832
krab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,
Спасибо за помощь :)
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648898
jab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svenom , почему нужно обновление с обоих сторон? У меня нормально работает с одной стороны.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648914
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jab svenom , почему нужно обновление с обоих сторон? У меня нормально работает с одной стороны.Это просто правило хорошего тона, что бы когда:
а) ваш код будет смотреть другой человек
б) ваш код будете смотреть вы же через N месяцев или после перепоя или невыспавшиймся
... сразу было ясно, что происходит. Если же вы не делаете обновление с другой стороны, то оно становится неявным, что значительно ухудшает читаемость кода и его интуитивное восприятие.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648923
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторsvenom, почему нужно обновление с обоих сторон? У меня нормально работает с одной стороны.
Не то чтобы оно уж так необходимо, просто это хорошая пратика, если у вас в течение реквеста идет работа только с одной сущностью, то все будет ок. Но представь такую ситуацию, ты работаешь с главной энтити, в которую добавляешь элемент коллекции, затем тебе надо перебрать коллекцию и сделать что-то с каждым элементом коллекции, и вот при этом что-то нужно иметь ссылку на парента, если не обновлять связи с двух сторон - то будет нулл поинтер, к тому же могут быть проблемы когда одна бизнес-транзакция распределена на несколько реквестов.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648926
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторваш код будете смотреть вы же через N месяцев или после перепоя или невыспавшиймся
... сразу было ясно, что происходит. Если же вы не делаете обновление с другой стороны, то оно становится неявным, что значительно ухудшает читаемость кода и его интуитивное восприятие.

Хороший поинт.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648953
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тут надо чётко знать что именно делает хибер.
Парент иногда нужен, если знать что именно он делает, и если он не делает в БД дополнительных полей (двойное сохранение).
Например, один чел в сети жалуется, что у него каскад не работает пока не добавил парента в child.
Спрашивается, какого лешего?
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37648960
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в субд не принято, делать запросы - загодя.
А вот в десктопе, в дереве элементов - принято (у каждого нода - парент на всякий случай)
Это из той же серии.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37649049
jab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я всегда думал, что добавляя чилд через парэнта и парэнта через чилд я получу в результате два парэнта и два чилда. Не проверял.
...
Рейтинг: 0 / 0
Hibernate @OneToMany @ManyToOne
    #37649060
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторА я всегда думал, что добавляя чилд через парэнта и парэнта через чилд я получу в результате два парэнта и два чилда. Не проверял.

Скорее всего при добавлении чайлда к паренту все будет ок, а вот когда делаешь child.setParent(parent), а потом parent.getChilds() - добавленный элемент может и не находится в коллекции. Давно не работал с хибернейт, но в какой-то версии точно были косяки
...
Рейтинг: 0 / 0
34 сообщений из 34, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate @OneToMany @ManyToOne
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]