Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Hibernate annotations, many-to-many


Автор: Galaran 14.9.2009, 06:05
Решил разобраться с Hibernate по туториалам http://java-course.ru/students/content.html

Схема базы: http://java-course.ru/students/part15.html
Проблема со связью многие-ко-многим PROFESSION - SUBJECT через SPECIALITY_SUBJECT

Маппинги:

Код

@Entity
@Table(name = "SUBJECT")
public class Subject {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "subject_id")
      private Long subjectId;

      @Column(name = "subject_name")
      private String subjectName;
      
      @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
      @JoinTable(name = "SPECIALITY_SUBJECT",
                 joinColumns = @JoinColumn(name = "subject_id"),
                 inverseJoinColumns = @JoinColumn(name = "profession_id"))
      private List<Profession> professionList;

      // getters - setters -------------------------------

      ...
}


Код

@Entity
@Table(name = "PROFESSION")
public class Profession {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "profession_id")
      private Long professionId;

      @Column(name = "profession_name")
      private String professionName;

      @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
      @JoinTable(name = "SPECIALITY_SUBJECT",
                 joinColumns = @JoinColumn(name = "profession_id"),
                 inverseJoinColumns = @JoinColumn(name = "subject_id"))
      private List<Subject> subjectList;

      // getters - setters ----------------------------------------------------------------

      ...
}


Запускаю:
Код

            System.out.println(dao.getSubjectList().size());
            System.out.println(dao.getSubjectList().get(0).getSubjectName());
            
            System.out.println(dao.getProfessionByName("Admin").getProfessionName());

            // Insert
            dao.getProfessionByName("Admin").getSubjectList().add(dao.getSubjectList().get(0));
            System.out.println(dao.getProfessionByName("Admin").getSubjectList().size());


используемые методы класса dao:

Код

public List<Subject> getSubjectList() {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            // HQL query
            List<Subject> result = session.createQuery("from Subject order by subjectName").list();
            session.getTransaction().commit();
            return result;
}

public Profession getProfessionByName(String prof) {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            Profession result = (Profession)session.createQuery(
                    "from Profession prof where prof.professionName = '" + prof + "'").uniqueResult();
            session.getTransaction().commit();
            return result;
}


Результат:

Код

1
Math
Admin
0


Т.е. видно, что hibernate находит Subject, находит Profession

А вот ассоциироваться они не хотят (пробовал 2 варианта)

Код

dao.getProfessionByName("Admin").getSubjectList().add(dao.getSubjectList().get(0));

Код

dao.getProfessionByName("Admin").setSubjectList(dao.getSubjectList());


Результат один и тот же. Где моя ошибка ?

Автор: Juggernaut 14.9.2009, 08:08
Добрый день.
Hibernate сохраняет в таблицу связей в момент коммита в БД.

Т.е. Ваш код сейчас работает примерно так:

Код

dao.getProfessionByName("Admin").//получили объект из БД
getSubjectList().add(dao.getSubjectList().get(0));//добавили в него другой объект-связь
//НЕ СОХРАНИЛИ            
System.out.println(dao.getProfessionByName("Admin").//опять получили тот же объект из БД
getSubjectList().size()); //FAIL


Я думаю надо так:
Код

dao.getProfessionByName("Admin").//получили объект из БД
getSubjectList().add(dao.getSubjectList().get(0));//добавили в него другой объект-связь
//вызвали метод сохранения или обновления (aka updateProfession())
System.out.println(dao.getProfessionByName("Admin").//опять получили объект из БД
getSubjectList().size()); //PROFIT


Автор: Galaran 15.9.2009, 08:35
Да, оно самое, спасибо

Код

System.out.println(dao.getProfessionByName("Test").getSubjectList().size());

Profession prof = dao.getProfessionByName("Test");
prof.getSubjectList().add(dao.getSubjectList().get(0));
dao.updateProfession(prof);

System.out.println(dao.getProfessionByName("Test").getSubjectList().size());


Код

0
1

?????
Действительно PROFIT  smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)