Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hibernate 
:(
    Опции темы
Tony
  Дата 1.8.2006, 01:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: 6
Всего: 12



Привет!
Начал учить Hibernate. Столкнулся с проблемой. Имею 2 класса (2 таблицы) и таблицу связи, состоящую из 2 колонок id first class и id second class.Пишу код
Код

        Session  session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        Author author=new Author();
        author.setFirstName("Боб");
        author.setSurname("Киллер");
        
        Book book=new Book();
        book.setIsbn("isbn:98439549");
        book.setTitle("Java_book");
        
        session.save(book);
        session.save(author);
        session.getTransaction().commit();

Как сделать чтобы в таблице связи были ID первого объекта, а во второй колонке ID второго объекта. Сейчас объекты сохраняются, но в таблице связи не создаётся строка.

Это сообщение отредактировал(а) tux - 1.8.2006, 08:13


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
tux
Дата 1.8.2006, 02:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



Насколько я понял у тебя здесь отношение между классами "многие-ко-многим". Тогда проще всего будет использовать соответствующие конструкции Hibernate. Предполагаем, что связующая таблица называется book_author и состоит из двух полей - book_id и author_id.

Класс Author:
Код

public class Author {
    private int authorId;
    private String authorName;
    private Set books;
    public int getAuthorId() {
        return authorId;
    }
    public void setAuthorId(int authorId) {
        this.authorId = authorId;
    }
    public String getAuthorName() {
        return authorName;
    }
    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }
    public Set getBooks() {
        return books;
    }
    public void setBooks(Set books) {
        this.books = books;
    }
}

Класс Book:
Код

public class Book {
    private int bookId;
    private String bookTitle;
    private Set authors;
    public Set getAuthors() {
        return authors;
    }
    public void setAuthors(Set authors) {
        this.authors = authors;
    }
    public int getBookId() {
        return bookId;
    }
    public void setBookId(int bookId) {
        this.bookId = bookId;
    }
    public String getBookTitle() {
        return bookTitle;
    }
    public void setBookTitle(String bookTitle) {
        this.bookTitle = bookTitle;
    }
}


Маппинг для класса Author:
Код

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="Author" table="author">

        <id name="authorId" column="author_id" type="int">
            <generator class="increment">
            </generator>
        </id>

        <property name="authorName" type="java.lang.String" 
            column="author_name" length="-1" not-null="true" />

        <set name="books" table="book_author" cascade="all">
            <key column="author_id"></key>
            <many-to-many column="book_id" class="Book" />
        </set>
    </class>

</hibernate-mapping>

Маппинг для класса Book:
Код

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="Book" table="book">

        <id name="bookId" column="book_id" type="int">
            <generator class="increment">
            </generator>
        </id>

        <property name="bookTitle" type="java.lang.String" 
            column="book_title" length="-1" not-null="true" />

        <set name="authors" table="book_author" cascade="all">
            <key column="book_id"></key>
            <many-to-many column="author_id" class="Author" />
        </set>
    </class>

</hibernate-mapping>

Ну и тестовый код:
Код

Transaction tr = session.beginTransaction();
        
Book book = new Book();
book.setBookTitle("Harry Potter");
Integer bookId = (Integer) session.save(book);
        
Author author = new Author();
author.setAuthorName("Джоан Роулинг");
Integer authorId = (Integer) session.save(author);
        
session.flush();
        
session.evict(book);
session.evict(author);
        
book = (Book) session.load(Book.class, bookId);
author = (Author) session.load(Author.class, authorId);
        
book.getAuthors().add(author);
session.save(book);
        
tr.commit();
session.close();

В результате в таблицу book_author должна добавиться одна запись. 

Небольшой комментарий. Здесь нужно отметить два момента. Первый - для работы с хранимыми множествами Hibernate использует собственные реализации интерфейсов типа Set, List и т.п. Второй - на протяжении сессии Hibernate хранит все объекты, с которыми выполнялась работа в кэше. Следовательно, для того, чтобы нормально сохранить в базу объекты, помещенные в Set нам нужно там иметь реализации Set от Hibernate. Казалось бы, можно просто сохранить объект (session.save()) и потом получить его у Hibernate (session.load()), но Hibernate в кэше сессии хранит оригинальные объекты и получим обратно тоже самое, что и сохранили, то есть объекты, в которых значения атрибутов books и authors равны null. Чтобы заставить Hibernate перегрузить объекты из базы, удаляем эти объекты из кэша выполнив session.evict(). 

В остальном думаю должно быть понятно.
PM MAIL Skype GTalk Jabber YIM   Вверх
batigoal
Дата 1.8.2006, 08:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 16
Всего: 151




Модератор: Сообщение скрыто.



--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
tux
Дата 1.8.2006, 08:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132




Модератор: Сообщение скрыто.

PM MAIL Skype GTalk Jabber YIM   Вверх
Tony
Дата 1.8.2006, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: 6
Всего: 12



Проблема была в маппинге.
Но я бе понал идею про:

Цитата

Небольшой комментарий. Здесь нужно отметить два момента. Первый - для работы с хранимыми множествами Hibernate использует собственные реализации интерфейсов типа Set, List и т.п. Второй - на протяжении сессии Hibernate хранит все объекты, с которыми выполнялась работа в кэше. Следовательно, для того, чтобы нормально сохранить в базу объекты, помещенные в Set нам нужно там иметь реализации Set от Hibernate. Казалось бы, можно просто сохранить объект (session.save()) и потом получить его у Hibernate (session.load()), но Hibernate в кэше сессии хранит оригинальные объекты и получим обратно тоже самое, что и сохранили, то есть объекты, в которых значения атрибутов books и authors равны null. Чтобы заставить Hibernate перегрузить объекты из базы, удаляем эти объекты из кэша выполнив session.evict(). 


и по4ему нельзя без
book = (Book) session.load(Book.class, bookId);
author = (Author) session.load(Author.class, authorId);
        
book.getAuthors().add(author); ?
если можно сразу при сайве session.save(); Тоесть приходится делать  save zatem load potom opat save dlja dobavlenja  book.getAuthors().add(author); ?

Это сообщение отредактировал(а) tux - 2.8.2006, 01:39


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
tux
Дата 2.8.2006, 01:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



Как я уже говорил, Hibernate реализует интерфейсы java.util.Set и другие подобные по-своему. Это в общем и понятно, ему там нужно хранить информацию о текущей сессии, об объекте, в котором есть атрибут типа Set. Чтобы получить в атрибутах объекта правильные реализации и правильно настроенные делается session.load() чтобы Hibernate сам построил объект как ему надо для корректной работы. 

В общем тот способ, который я привел - единственное что удалось придумать для такой задачи. Если у тебя получится короче и изящнее, буду только рад. Если найдешь решение, не забудь код запостить сюда. smile
PM MAIL Skype GTalk Jabber YIM   Вверх
Tony
Дата 3.8.2006, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: 6
Всего: 12



Я хотел спросить по4ему ты делел так save-->load-->save когда можно сразу save.


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0535 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.