Reputation: 31
I'm trying to map some existing tables with Hibernate.
It's quite simple: we've got categories that have names in multiple languages.
The DDL is as follows:
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)
);
Now I'd like to have a map with Language as it's key and Description (table category_description) as it's value, like this:
private Map<Language, CategoryDescription> descriptions = new HashMap<Language, CategoryDescription>();
Can anyone provide me with some pointers on this? I've tried the example as given on page 311/312 from the 'Java Persistence with Hibernate' which resembles my problem but I'm just not getting it :(
Upvotes: 3
Views: 3888
Reputation: 11696
(Your DDL is inconsistent, you create a table "language" but reference a table "country_language" -- I will assume the latter)
Here is what the Hibernate mapping for your sample would look like:
<?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>
However, you don't need the CategoryDescription
class at all (as it just wraps a String
):
private Map<Language, String> descriptions;
and
<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>
would work just as well.
Note that in both cases your Language
class would need to override hashCode()
and equals()
in order to be able to successfully query the resulting map:
/* 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;
}
Upvotes: 2