Hibernate many-to-many with composite key and extra column

A hibernate many-to-many relationship example with composite primary key and an extra column in the ‘third table’.
We make three java files Product.java, Category, ProductCategory.java
The source code for the three files is:

Product.java

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * @author Panos Bariamis
 */
@Entity
@Table(name="products")
public class Product implements Serializable {
 @Id
 private Long id;
 
 private String title;
 
 @OneToMany(mappedBy="pk.product") 
 private Set<ProductCategory> categories = new HashSet<ProductCategory>();
 
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((id == null) ? 0 : id.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Product other = (Product) obj;
  if (id == null) {
   if (other.id != null)
    return false;
  } else if (!id.equals(other.id))
   return false;
  return true;
 }

 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<ProductCategory> getCategories() {
  return categories;
 }

 public void setCategories(Set<ProductCategory> categories) {
  this.categories = categories;
 }
}

Category.java

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * @author Panos Bariamis
 */
@Entity
@Table(name="products")
public class Category implements Serializable {
 @Id
 private Long id;
 
 private String title;
 
 @OneToMany(mappedBy="pk.category") 
 private Set<ProductCategory> products = new HashSet<ProductCategory>();
 
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((id == null) ? 0 : id.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Category other = (Category) obj;
  if (id == null) {
   if (other.id != null)
    return false;
  } else if (!id.equals(other.id))
   return false;
  return true;
 }

 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<ProductCategory> getProducts() {
  return products;
 }

 public void setProducts(Set<ProductCategory> products) {
  this.products = products;
 }
}

ProductCategory.java (the ‘third table’)

import java.io.Serializable;

import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * @author Panos Bariamis
 */
@Entity @Table(name="products_categories")
@AssociationOverrides({
 @AssociationOverride(name="pk.product", joinColumns = @JoinColumn(name="product_id")),
 @AssociationOverride(name="pk.category", joinColumns = @JoinColumn(name="category_id"))
})
public class ProductCategory implements Serializable {
 @Id
 private ProductCategoryPK pk = new ProductCategoryPK();
 
 private int ordinal;
 
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((pk == null) ? 0 : pk.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  ProductCategory other = (ProductCategory) obj;
  if (pk == null) {
   if (other.pk != null)
    return false;
  } else if (!pk.equals(other.pk))
   return false;
  return true;
 }

 public ProductCategoryPK getPk() {
  return pk;
 }

 public void setPk(ProductCategoryPK pk) {
  this.pk = pk;
 }

 public int getOrdinal() {
  return ordinal;
 }

 public void setOrdinal(int ordinal) {
  this.ordinal = ordinal;
 }
}

@Embeddable
class ProductCategoryPK implements Serializable {
 @ManyToOne
 private Product product;
 
 @ManyToOne
 private Category category;

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

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  ProductCategoryPK other = (ProductCategoryPK) obj;
  if (category == null) {
   if (other.category != null)
    return false;
  } else if (!category.equals(other.category))
   return false;
  if (product == null) {
   if (other.product != null)
    return false;
  } else if (!product.equals(other.product))
   return false;
  return true;
 }
 
 public Product getProduct() {
  return product;
 }

 public void setProduct(Product product) {
  this.product = product;
 }

 public Category getCategory() {
  return category;
 }

 public void setCategory(Category category) {
  this.category = category;
 }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s