tags:

views:

376

answers:

4

I'm trying to create an address book application with one table for People, another for Companies and a third one for Phones. The Phones table will have the data for the People and the Companies with a field indicating where it came from. Let's assume that these are the simple tables:

CREATE TABLE `Person` {
  `id` int(11) NOT NULL auto_increment,
  `firstName` varchar(80) NOT NULL,
  `lastName` varchar(80) NOT NULL
}

CREATE TABLE `Company` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(80) NOT NULL
}

CREATE TABLE `ContactPhone` (
  `id` int(11) NOT NULL auto_increment,
  `contactType` char(1) NOT NULL, -- either 'P' or 'C'
  `contactId` int(11) NOT NULL, -- the id of the Person or Company
  `number` varchar(40) NOT NULL
}

I have created their corresponding java classes which are a very simple representation:

public class Person {
  private Integer id;
  private String firstName;
  private String lastName;
  private Collection<Phone> phones;
  // ...
}

public class Company {
  private Integer id;
  private String name;
  private Collection<Phone> phones;
  // ...
}

public class Phone {
  private Integer id;
  private String number;
  // ...
}

In plain SQL I can get the person and corresponding phones very easily. I need to create a mapping between Person and Phone and between Company and Phone using plain hibernate (no annotations) but can't get it to work. Not even sure if it has to be unidirectional or bidirectional. I have searched for the documentation but haven't found anything that can help. Anyone?

A: 

You could achieve this using the "Filters" mapping feature of Hibernate

lomaxx
It seems this would work when loading an object, but how about when persisting the object? How will the correct value get inserted into the contactType of the ContactPhone table?
rmarimon
A: 

If you're asking how to map them through a mapping table in the config file it would look something like this:

<bag name="Phone" table="CompanyPhoneMapping" lazy="true" cascade="all">

<key column="CompanyId" />

<one-to-many class=<insert namespace>.Phone, <insert dll> />

</bag>

I am only familiar with nhibernate, but I assume the java hibernate solution would be similar.

ebrown
+1  A: 

Finally I managed to get this working. What I was looking for was the polymorphism elements of hibernate. I ended up creating a Contact class as follows:

public class Contact {
  private Integer id;
  private Collection<Phone> phones;
  ...
}

and derived Person and Company from it. With Hibernate's polymorphism it is possible to store Person and Company in different tables and have Phone connect to Contact in bidirectional way.

rmarimon
This is one way to do it. See my post for another way.
Paul Morie
A: 

The accepted with to model this is as a unidirectional association with a join table in the Person and Company classes. How this is achieved exactly depends on the specifics of your model. The online documentation is here.

Paul Morie