2010-10-02 9 views
0

J'essaie de construire une application en utilisant Hibernate pour la persistance (mon premier). L'application a des genres et des livres. La classe de genre a un ensemble de livres. Mais chaque livre de l'ensemble a la valeur 0 (idGenre) (clé étrangère). Je pense que le mappage n'est pas correct. S'il vous plaît dites-moi où est l'erreur. Merci.Pourquoi la valeur de la clé étrangère est toujours zéro?

Voici la mise en correspondance:

<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> 

Voici où je charge les livres:

Session s = sessionFactory.openSession(); 

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

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

Voici la classe du livre:

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; 
    } 

} 

Voici comment je fais nouvelle instance d'un livre:

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

Et le saveGenre (g) méthode (sans initialisation de SessionFactory et session et transaction):

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

Répondre

2

Votre carte semble OK pour moi à première vue . Mon soupçon est que vous ne pouvez pas associer correctement vos entités Book avec le Genre correspondant. Pourriez-vous poster le code pour créer et persister Book s?

Mise à jour: votre code ressemble à cela pourrait fonctionner, même si on ne sait pas pourquoi vous merge votre genre (si vous travaillez avec vos entités autrement détachés durant les conversations couvrant plusieurs sessions, il est OK, peut être trop compliquer la image). Et la définition de Genre.addBook est manquante, mais je suppose que vous l'avez fait correctement :-)

Ma nouvelle observation est que vous n'avez pas mappé Book.idGenre. Essayez de prolonger votre application comme ceci:

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

Comme une note de côté, cela fait aussi partie des attributs de l'autre côté de la redondance d'association - vous pouvez simplifier comme ceci:

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

Update2: oups, et une chose: remplacer long idGenre avec une Genre propriété Book, comme

private Genre genre; 

et bien sûr mettre à jour getter/setter, et mapper en conséquence.

+0

J'ai modifié la question. Merci – DaJackal

+0

@DaJackal, ce code définit uniquement la classe 'Book', et récupère les instances existantes de la base de données. Comment créez-vous de nouvelles instances de "Livre" et associez-les à un "Genre"? –

+0

J'espère que maintenant je mets tout le code. – DaJackal