Почему значение внешнего ключа всегда равно нулю? - PullRequest
0 голосов
/ 02 октября 2010

Я пытаюсь создать какое-нибудь приложение, используя hibernate для сохранения (мой первый). В приложении есть жанры и книги. У жанрового класса есть набор книг. Но каждая книга в наборе имеет значение idGenre (внешний ключ) 0. Я думаю, что отображение не верно. Пожалуйста, скажите мне, где ошибка. Спасибо.

Вот отображение:

<hibernate-mapping package = "model">

   <class name = "User" table="virtual_bookcase.users">
        <id name = "id" column = "id" type = "long">
            <generator class = "increment"/>
        </id>
        <property name = "username" column = "username" type = "string"/>
        <property name = "password" column = "password" type = "string"/>
   </class>

   <class name = "Genre" table = "virtual_bookcase.genres">
      <id name = "id" column = "idGenres" type = "long">
        <generator class = "increment"/>
      </id>   
      <property name = "name" column = "name" type = "string"/>
      <set name = "books" table = "virtual_bookcase.books" cascade = "all-delete-orphan">
        <key column = "idGenre" not-null = "true" />
        <one-to-many class = "Book"/>
      </set>
      <many-to-one name = "user" class = "User" column = "user_id" />
   </class>

   <class name = "Book" table = "virtual_bookcase.books">
        <id name = "id" column = "idBooks" type = "long">
         <generator class = "increment"/>
        </id>
        <property name = "title" column = "title" type = "string"/>
        <property name = "author" column = "author" type = "string"/>
        <property name = "publisher" column = "publisher" type = "string"/>
        <property name = "pages" column = "pages" type = "short"/>
        <property name = "borrowed" column = "borrowed" type = "byte"/>
        <property name = "borrowedTo" column = "borrowedTo" type = "string"/>
   </class>

</hibernate-mapping>

Вот где я загружаю книги:

Session s = sessionFactory.openSession();

Query q = s.createQuery("FROM Book WHERE idGenre = ?").setLong(0, g.getId());

books = new TreeSet<Book>(q.list());

Вот класс Книги:

public class Book implements Comparable<Book>
{
    private long id;
    private String title;
    private String author;
    private String publisher;
    private short pages;
    private byte borrowed;
    private String borrowedTo;
    private long idGenre;

public Book(){}
    public Book(String title, String author, String publisher, short pag, byte borrowed, String borrowedTo, long idGenre)
    {
        this.title = title;
        this.author = author;
        this.publisher = publisher;
        this.pages = pag;
        this.borrowed = borrowed;
        this.borrowedTo = borrowedTo;
        this.idGenre = idGenre;
    }

    public long getId()
    {
        return id;
    }

    public String getTitle()
    {
        return title;
    }

    public String getAuthor()
    {
        return author;
    }

    public String getPublisher()
    {
        return publisher;
    }

    public short getPages()
    {
        return pages;
    }

    public void setId(long id)
    {
        this.id = id;
    }

    public void setTitle(String title)
    {
        this.title = title;
    }

    public void setAuthor(String author)
    {
        this.author = author;
    }

    public void setPublisher(String publisher)
    {
        this.publisher = publisher;
    }

    public void setPages(short pages)
    {
        this.pages = pages;
    }

    public byte getBorrowed()
    {
        return borrowed;
    }

    public void setBorrowed(byte borrowed)
    {
        this.borrowed = borrowed;
    }

    public String getBorrowedTo()
    {
        return borrowedTo;
    }

    public void setBorrowedTo(String borrowedTo)
    {
        this.borrowedTo = borrowedTo;
    }

    public long getIdGenre()
    {
        return idGenre;
    }

    public void setIdGenre(long idGenre)
    {
        this.idGenre = idGenre;
    }

    @Override
    public String toString()
    {
        return title;
    }

    @Override
    public int compareTo(Book b)
    {
        if (this.title == b.getTitle() && this.author == b.getAuthor() && this.publisher == b.getPublisher() && this.pages == b.getPages())
            return 0;
        return 1;
    }

}

Вот как я делаю новый экземпляр Книги:

Book b = new Book("AddedBook", "A", "A", (short) 555, (byte) 0, "", 1);
Genre g = ((Genre) cmbGenres.getSelectedItem());
g.addBook(b);
control.saveGenre(g);

И метод saveGenre (g) (без инициализации SessionFactory, сеанса и транзакции):

   t = session.beginTransaction();
   Genre gr = (Genre) session.merge(g);
   t.commit();

1 Ответ

2 голосов
/ 02 октября 2010

Ваше отображение выглядит нормально для меня с первого взгляда . Я подозреваю, что вы не можете правильно связать свои Book сущности с соответствующими Genre. Не могли бы вы опубликовать код для создания и сохранения Book s?

Обновление: ваш код выглядит так, как будто он может работать, хотя неясно, почему вы merge свой жанр (если вы работаете со своими сущностями в отключенном состоянии во время разговоров, охватывающих несколько сеансов, это нормально, в противном случае это может усложнить картину). И определение Genre.addBook отсутствует, но я предполагаю, что вы все сделали правильно: -)

Мое новое наблюдение - вы не нанесли на карту Book.idGenre. Попробуйте расширить свое отображение так:

<class name = "Book" table = "virtual_bookcase.books">
    ...
    <many-to-one name="idGenre" column="idGenre" class="Genre" not-null="true"/>
</class>

Как примечание, это также делает некоторые атрибуты на другой стороне ассоциации избыточными - вы можете упростить это следующим образом:

  <set name = "books" cascade = "all-delete-orphan">
    <key column = "idGenre"/>
    <one-to-many class = "Book"/>
  </set>

Update2: упс, и еще одна вещь: замените long idGenre свойством Genre в Book, например

private Genre genre;

и, конечно, обновите getter / setter и соответственно отобразите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...