These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Many-to-Many XML Mapping with extra columns
PostPosted: Wed Dec 21, 2011 12:48 pm 
Newbie

Joined: Sat Apr 23, 2011 3:50 pm
Posts: 3
Brief schema

Code:
TABLE_BOOK
BOOK_ID
BOOK_TITLE

TABLE_AUTHOR
AUTHOR_ID
AUTHOR_NAME

TABLE_BOOKAUTHOR
BOOK_AUTHOR_ID
BOOK_ID
AUTHOR_ID
PRIMARY_AUTHOR (BOOLEAN)
AUTHOR_TYPE_REF_ID (Referes to a table reference_data)

TABLE_REFERENCE_DATA
REF_DATA_ID
REF_DATA_LABEL

What I am looking for is a way to map the authors, through Book Author, into the book class while retaining the extra columns in the book author table.

(And I did try using the search, but apparently many-to-many is considered to be too common a word, as are XML and mapping).

My current POJOs look like this:
Code:
package com.hometools.hibernate.library;

import java.util.List;
import java.util.Set;

public class Book {
   private Long id;
   private String title;
   private Set<Author> authors;   
   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      this.id = id;
   }
   public String getTitle() {
      return title;
   }
   public void setTitle(String title) {
      this.title = title;
   }
   public Set<Author> getAuthors() {
      return authors;
   }
   public void setAuthors(Set<Author> authors) {
      this.authors = authors;
   }
}


Code:
package com.hometools.hibernate.library;

public class Author {
   private Long id;
   private String lastName;
   private String firstName;
   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      this.id = id;
   }
   public String getLastName() {
      return lastName;
   }
   public void setLastName(String lastName) {
      this.lastName = lastName;
   }
   public String getFirstName() {
      return firstName;
   }
   public void setFirstName(String firstName) {
      this.firstName = firstName;
   }
}


And the XML Mappings:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 15, 2011 12:58:24 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.hometools.hibernate.library.Book" table="BOOK">
        <id name="id" type="java.lang.Long">
            <column name="BOOK_ID" />
            <generator class="sequence">
               <param name="sequence">BOOK_SEQ</param>
            </generator>
        </id>
        <property name="title" type="java.lang.String">
            <column name="BOOK_TITLE" />
        </property>
        <set name="authors" table="BOOK_AUTHOR">
           <key column="BOOK_ID"/>
           <many-to-many column="AUTHOR_ID" class="com.hometools.hibernate.library.Author"/>
        </set>
    </class>
</hibernate-mapping>


Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 15, 2011 12:23:40 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.hometools.hibernate.library.Author" table="AUTHOR">
        <id name="id" type="java.lang.Long">
            <column name="AUTHOR_ID" />
            <generator class="sequence">
               <param name="sequence">AUTHOR_SEQ</param>
            </generator>
        </id>
        <property name="lastName" type="java.lang.String">
            <column name="AUTHOR_LAST_NAME" />
        </property>
        <property name="firstName" type="java.lang.String">
            <column name="AUTHOR_FIRST_NAME" />
        </property>
    </class>
</hibernate-mapping>


This does work, and it returns me the list of authors for each book, but I would really like to be able to retreive those extra columns using an XML mapping. I know there are solutions for this using annotations, but I'd like to stick with the XML if that's possible.


Top
 Profile  
 
 Post subject: Re: Many-to-Many XML Mapping with extra columns
PostPosted: Thu Dec 22, 2011 12:26 pm 
Newbie

Joined: Sat Apr 23, 2011 3:50 pm
Posts: 3
Ok, I did solve it using some information from the Hibernate FAQ at this location:
http://community.jboss.org/wiki/HibernateFAQ-TipsAndTricks#I_have_a_manytomany_association_between_two_tables_but_the_association_table_has_some_extra_columns_apart_from_the_foreign_keys_What_kind_of_mapping_should_I_use

First, I defined a new class - BookAuthor to represent the join and the extra data:
Code:
package com.hometools.hibernate.library;

public class BookAuthor {
   private Author author;
   private Boolean primaryAuthor;
   private ReferenceData authorType;
   public Author getAuthor() {
      return author;
   }
   public void setAuthor(Author author) {
      this.author = author;
   }
   public Boolean getPrimaryAuthor() {
      return primaryAuthor;
   }
   public void setPrimaryAuthor(Boolean primaryAuthor) {
      this.primaryAuthor = primaryAuthor;
   }
   public ReferenceData getAuthorType() {
      return authorType;
   }
   public void setAuthorType(ReferenceData authorType) {
      this.authorType = authorType;
   }
   

}



This class does not get a mapping file.

Second I added the following to my Book.java class:
Code:
private Set<BookAuthor> authors;
...
   public Set<BookAuthor> getAuthors() {
      return authors;
   }
   public void setAuthors(Set<BookAuthor> authors) {
      this.authors = authors;
   }


And the Book.hbm mapping file:

Code:
        <set name="authors" table="BOOK_AUTHOR">
           <key column="BOOK_ID"/>
           <composite-element class="com.hometools.hibernate.library.BookAuthor">
              <many-to-one name="author" column="AUTHOR_ID" class="com.hometools.hibernate.library.Author" />
              <many-to-one name="authorType" column="AUTHOR_TYPE_REF_ID" class="com.hometools.hibernate.library.ReferenceData" />
              <property name="primaryAuthor" type="java.lang.Boolean" column="PRIMARY_AUTHOR" />
           </composite-element>
           
        </set>


This allows me to reference the extra columns in book author through the authors set.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.