我尝试使用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();
答案 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,并相应地进行映射。