A very common database design pattern is when you have a many-to-many table which creates a 3th table to create the many to many. You don't have to create a POJO for the 3th table but simply map the many-to-many between the two tables. But what if you want an extra property in your 3th table. You have to create a POJO with a primary key over multiple columns. But the columns exists of foreign keys to the other table's primary key. Notice you have to use the latest hibernate-annotations beta10.
Here's the picture to clarify it a bit:

And here is the code:
@Entity
@Table(name = "Product")
public class Product extends AbstractRecordImpl
{
@NotNull private String name;
private String description;
//----bidirectional association
@OneToMany(mappedBy="product")
private ListproductItems = new ArrayList ();
//----
//Some getters & setters
...
}
@Entity
@Table(name = "Item")
public class Item extends AbstractRecordImpl
{
@NotNull private String name;
//----bidirectional association
@OneToMany(mappedBy="item")
private ListproductItems = new ArrayList ();
//----
//Some getters & setters
...
}
Easy so far, just the normal POJO's.. Now for the magic:
I've added 2 extra getters and setters for Product and Item to make it easier to get or set a product or item on your primary key. I added to extra columns to make hibernate think there is a Product mapped to this table (and an Item) but hibernate never updates or inserts this property (becuase it doensn't exists in our db.) But when hibernate does the getProduct() method it will retrieve the Product from our composite foreign key and all will work fine! ^_^
@Entity
@Table(name = "ProductItem")
public class ProductItem
{
@Id
private ProductItemPK primaryKey = new ProductItemPK();
private String description;
//bidirectional association! Needed to trick hibernate ;P
@SuppressWarnings("unused")
@Column(name="item_id", nullable=false, updatable=false, insertable=false)
private Long item;
@SuppressWarnings("unused")
@Column(name="product_id", nullable=false, updatable=false, insertable=false)
private Long product;
//----
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void setProduct(Product product) {
primaryKey.setProduct(product);
}
public Product getProduct(){
return primaryKey.getProduct();
}
public void setItem(Item item) {
primaryKey.setItem(item);
}
public Item getItem() {
return primaryKey.getItem();
}
}
@Embeddable
private class ProductItemPK implements Serializable
{
@ManyToOne
private Item item;
@ManyToOne
private Product product;
//Some getters and setters
...
}

