为什么外键的值总是为零?

时间:2010-10-02 12:24:22

标签: java hibernate orm

我尝试使用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());

这是Book类:

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 个答案:

答案 0 :(得分:2)

您的地图一见即可。我怀疑您可能无法将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: oops,还有一件事:将long idGenre替换为Genre中的Book属性,例如

private Genre genre;

当然更新getter / setter,并相应地进行映射。