2009-05-12 12 views
3

J'essaie de mapper certaines tables existantes avec Hibernate.Hibernate: mappage 3 tables

C'est assez simple: nous avons des catégories qui ont des noms dans plusieurs langues.

ddl est comme suit:

create table language (
    id    integer not null auto_increment, 
    code    varchar(2) not null, 

    unique (code), 

    primary key(id) 
); 

create table category (
    id    integer not null auto_increment, 
    parent_id  integer default null, 
    ordr    integer not null default 99, 

    primary key (id) 
); 

create table category_description (
    category_id  integer not null, 
    language_id  integer not null, 

    title   varchar(255) not null, 

    constraint foreign key (category_id) references category(id), 
    constraint foreign key (country_language_id) references country_language(id), 

    primary key (category_id, country_language_id) 
); 

Maintenant, je voudrais avoir une carte avec la langue comme il est et la description (tableau category_description) comme sa valeur, comme ceci:

private Map<Language, CategoryDescription> descriptions = new HashMap<Language, CategoryDescription>(); 

Quelqu'un peut-il me fournir quelques indications à ce sujet? J'ai essayé l'exemple comme indiqué à la page 311/312 de 'Java Persistence with Hibernate' qui ressemble à mon problème mais je ne comprends pas :(

Répondre

2

(Votre DDL est incohérent, vous créez une table " langue », mais référence à une table « country_language » - Je suppose que celui-ci)

Voici ce que le mapping Hibernate pour votre échantillon ressemblerait à ceci:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping default-lazy="false"> 

    <class name="Language" table="country_language"> 
     <id name="id" type="int"> 
      <column name="ID" /> 
      <generator class="native" /> 
     </id> 
     <property name="code" type="string" length="2" unique="true" /> 
    </class> 

    <class name="Category" table="category"> 
     <id name="id" type="int"> 
      <column name="ID" /> 
      <generator class="native" /> 
     </id> 
     <map name="descriptions" table="category_description"> 
      <key column="category_id" /> 
      <map-key-many-to-many column="language_id" class="Language" /> 
      <composite-element class="CategoryDescription"> 
       <property name="title" type="string" length="255" /> 
      </composite-element> 
     </map> 
    </class> 

</hibernate-mapping> 

Cependant, vous n'avez pas besoin CategoryDescription classe du tout (comme il vient d'envelopper un String):

private Map<Language, String> descriptions; 

et

<map name="descriptions" table="category_description"> 
    <key column="category_id" /> 
    <map-key-many-to-many column="language_id" class="Language" /> 
    <element type="string" length="255" column="title" /> 
</map> 

fonctionnerait aussi bien.

Notez que dans les deux cas, votre classe Language aurait besoin de passer outre hashCode() et equals() afin de pouvoir interroger avec succès la carte résultante:

/* eclipse generated */ 
@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((id == null) ? 0 : id.hashCode()); 
    return result; 
} 

/* eclipse generated */ 
@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    Language other = (Language) obj; 
    if (id == null) { 
     if (other.id != null) 
      return false; 
    } else if (!id.equals(other.id)) 
     return false; 
    return true; 
} 
+0

Salut, Merci beaucoup pour la réponse. Nous avons travaillé autour d'elle d'une manière que je n'aime pas mais j'essaierai certainement ceci dehors. Vous avez raison à propos de l'incohérence DDL; J'ai essayé de "simplifier" un peu les choses mais de toute évidence manqué quelque chose. À cet égard, la description de la catégorie a également été simplifiée, avec quelques attributs supplémentaires. Nous avons la même configuration à 3 tables pour d'autres entités (beaucoup de nos entités ont des descriptions multilingues qui sont conçues de la même manière) Je posterai de nouveau dès que je trouverai le temps d'essayer votre solution. Merci. – user90209

Questions connexes