title: Hibernate – Many-To-Many Example – Join Table + Extra Column (Annotation)
body: <p>Person entity have many to many relation with Bank entity through personBankAssociation
  While saving the person entity i m getting error as
  Hibernate: /* insert SampleJavaProject.Entity.Bank */ insert into test.Bank (amount, name) values (?, ?)
  Exception in thread "main" java.lang.NullPointerException
      at SampleJavaProject.Entity.PersonBankAssociation.setPerson(PersonBankAssociation.java:97)
      at SampleJavaProject.HibernateTransaction.PersonBankApp.main(PersonBankApp.java:57)</p>
  
  <pre><code>/**
   * 
   */
  package SampleJavaProject.Entity;
  
  import java.io.Serializable;
  import java.util.Calendar;
  import java.util.Set;
  
  import javax.persistence.CascadeType;
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.FetchType;
  import javax.persistence.GeneratedValue;
  import javax.persistence.GenerationType;
  import javax.persistence.Id;
  import javax.persistence.OneToMany;
  import javax.persistence.Table;
  
  /**
   * @author Siddhant_S
   * 
   */
  @Entity
  @Table(name = "person", schema = "test")
  public class Person implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name="person_id")
      private int id;
      private String name;
      @Column(precision = 2)
      private double amount;
      private Calendar birthDate;
      private String street;
      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "pk.person")
      private Set&lt;PersonBankAssociation&gt; bank;
  
      /**
       * 
       */
      public Person() {
      }
  
      /**
       * @param name
       * @param amount
       * @param birthDate
       * @param street
       * @param bank
       */
      public Person(String name, double amount, Calendar birthDate, String street) {
          this.name = name;
          this.amount = amount;
          this.birthDate = birthDate;
          this.street = street;
          this.bank = bank;
      }
  
      /**
       * @return the id
       */
      public int getId() {
          return id;
      }
  
      /**
       * @param id
       *            the id to set
       */
      public void setId(int id) {
          this.id = id;
      }
  
      /**
       * @return the name
       */
      public String getName() {
          return name;
      }
  
      /**
       * @param name
       *            the name to set
       */
      public void setName(String name) {
          this.name = name;
      }
  
      /**
       * @return the amount
       */
      public double getAmount() {
          return amount;
      }
  
      /**
       * @param amount
       *            the amount to set
       */
      public void setAmount(double amount) {
          this.amount = amount;
      }
  
      /**
       * @return the birthDate
       */
      public Calendar getBirthDate() {
          return birthDate;
      }
  
      /**
       * @param birthDate
       *            the birthDate to set
       */
      public void setBirthDate(Calendar birthDate) {
          this.birthDate = birthDate;
      }
  
      /**
       * @return the street
       */
      public String getStreet() {
          return street;
      }
  
      /**
       * @param street
       *            the street to set
       */
      public void setStreet(String street) {
          this.street = street;
      }
  
      /**
       * @return the bank
       */
      public Set&lt;PersonBankAssociation&gt; getBank() {
          return bank;
      }
  
      /**
       * @param bank
       *            the bank to set
       */
      public void setBank(Set&lt;PersonBankAssociation&gt; bank) {
          this.bank = bank;
      }
  }
  
  Bank entity
  
  /**
   * 
   */
  package SampleJavaProject.Entity;
  
  import java.io.Serializable;
  import java.util.Set;
  
  import javax.persistence.CascadeType;
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.FetchType;
  import javax.persistence.GeneratedValue;
  import javax.persistence.GenerationType;
  import javax.persistence.Id;
  import javax.persistence.OneToMany;
  import javax.persistence.Table;
  
  /**
   * @author Siddhant_S
   * 
   */
  @Entity
  @Table(name = "Bank", schema = "test")
  public class Bank implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name="bank_id")
      private int id;
      private String name;
      @Column(precision = 2)
      private double amount;
      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "pk.bank")
      private Set&lt;PersonBankAssociation&gt; associations;
  
      /**
       * 
       */
      public Bank() {
      }
  
      /**
       * @param name
       * @param amount
       * @param associations
       */
      public Bank(String name, double amount) {
          this.name = name;
          this.amount = amount;
      }
  
      /**
       * @return the id
       */
      public int getId() {
          return id;
      }
  
      /**
       * @param id
       *            the id to set
       */
      public void setId(int id) {
          this.id = id;
      }
  
      /**
       * @return the name
       */
      public String getName() {
          return name;
      }
  
      /**
       * @param name
       *            the name to set
       */
      public void setName(String name) {
          this.name = name;
      }
  
      /**
       * @return the amount
       */
      public double getAmount() {
          return amount;
      }
  
      /**
       * @param amount
       *            the amount to set
       */
      public void setAmount(double amount) {
          this.amount = amount;
      }
  
      /**
       * @return the associations
       */
      public Set&lt;PersonBankAssociation&gt; getAssociations() {
          return associations;
      }
  
      /**
       * @param associations
       *            the associations to set
       */
      public void setAssociations(Set&lt;PersonBankAssociation&gt; associations) {
          this.associations = associations;
      }
  }
  
  Association
  
  
  /**
   * 
   */
  package SampleJavaProject.Entity;
  
  import java.io.Serializable;
  
  import javax.persistence.AssociationOverride;
  import javax.persistence.AssociationOverrides;
  import javax.persistence.EmbeddedId;
  import javax.persistence.Entity;
  import javax.persistence.JoinColumn;
  import javax.persistence.Table;
  import javax.persistence.Transient;
  
  /**
   * @author Siddhant_S
   * 
   */
  @Entity
  @Table(name = "Person_Bank_Association", schema = "test")
  @AssociationOverrides({
          @AssociationOverride(name = "pk.person", joinColumns = @JoinColumn(name = "person_id")),
          @AssociationOverride(name = "pk.bank", joinColumns = @JoinColumn(name = "bank_id")) })
  public class PersonBankAssociation implements Serializable {
      @EmbeddedId
      private PersonBankId pk;
      private String name;
      private double amount;
      /**
       * 
       */
      public PersonBankAssociation() {
      }
      /**
       * @param name
       * @param amount
       */
      public PersonBankAssociation(String name, double amount) {
          this.name = name;
          this.amount = amount;
      }
      /**
       * @return the pk
       */
      public PersonBankId getPk() {
          return pk;
      }
      /**
       * @param pk
       *            the pk to set
       */
      public void setPk(PersonBankId pk) {
          this.pk = pk;
      }
  
      /**
       * @return the name
       */
      public String getName() {
          return name;
      }
  
      /**
       * @param name
       *            the name to set
       */
      public void setName(String name) {
          this.name = name;
      }
  
      /**
       * @return the amount
       */
      public double getAmount() {
          return amount;
      }
  
      /**
       * @param amount
       *            the amount to set
       */
      public void setAmount(double amount) {
          this.amount = amount;
      }
  
      /**
       * 
       * @return person
       */
      @Transient
      public Person getPerson() {
          return getPk().getPerson();
      }
  
      public void setPerson(Person person) {
          getPk().setPerson(person);
      }
  
      /**
       * 
       * @return bank
       */
      @Transient
      public Bank getBank() {
          return getPk().getBank();
      }
  
      public void setBank(Bank bank) {
          getPk().setBank(bank);
      }
      /* (non-Javadoc)
       * @see java.lang.Object#hashCode()
       */
      @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + ((pk == null) ? 0 : pk.hashCode());
          return result;
      }
      /* (non-Javadoc)
       * @see java.lang.Object#equals(java.lang.Object)
       */
      @Override
      public boolean equals(Object obj) {
          if (this == obj)
              return true;
          if (obj == null)
              return false;
          if (getClass() != obj.getClass())
              return false;
          PersonBankAssociation other = (PersonBankAssociation) obj;
          if (pk == null) {
              if (other.pk != null)
                  return false;
          } else if (!pk.equals(other.pk))
              return false;
          return true;
      }
  
  
  }
  
  Relatation
  
  /**
   * 
   */
  package SampleJavaProject.Entity;
  
  import java.io.Serializable;
  
  import javax.persistence.CascadeType;
  import javax.persistence.Embeddable;
  import javax.persistence.FetchType;
  import javax.persistence.ManyToOne;
  
  /**
   * @author Siddhant_S
   * 
   */
  @Embeddable
  public class PersonBankId implements Serializable {
      @ManyToOne
      private Person person;
      @ManyToOne
      private Bank bank;
  
      /**
       * 
       */
      public PersonBankId() {
      }
  
      /**
       * @return the person
       */
      public Person getPerson() {
          return person;
      }
  
      /**
       * @param person
       *            the person to set
       */
      public void setPerson(Person person) {
          this.person = person;
      }
  
      /**
       * @return the bank
       */
      public Bank getBank() {
          return bank;
      }
  
      /**
       * @param bank
       *            the bank to set
       */
      public void setBank(Bank bank) {
          this.bank = bank;
      }
  
      /*
       * (non-Javadoc)
       * 
       * @see java.lang.Object#hashCode()
       */
      @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + ((bank == null) ? 0 : bank.hashCode());
          result = prime * result + ((person == null) ? 0 : person.hashCode());
          return result;
      }
  
      /*
       * (non-Javadoc)
       * 
       * @see java.lang.Object#equals(java.lang.Object)
       */
      @Override
      public boolean equals(Object obj) {
          if (this == obj)
              return true;
          if (obj == null)
              return false;
          if (getClass() != obj.getClass())
              return false;
          PersonBankId other = (PersonBankId) obj;
          if (bank == null) {
              if (other.bank != null)
                  return false;
          } else if (!bank.equals(other.bank))
              return false;
          if (person == null) {
              if (other.person != null)
                  return false;
          } else if (!person.equals(other.person))
              return false;
          return true;
      }
  
  }
  
  Saving code
  
  /**
   * 
   */
  package SampleJavaProject.HibernateTransaction;
  
  import java.util.Calendar;
  import java.util.Date;
  import java.util.GregorianCalendar;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Set;
  
  import org.hibernate.Session;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import SampleJavaProject.Entity.Bank;
  import SampleJavaProject.Entity.Person;
  import SampleJavaProject.Entity.PersonBankAssociation;
  import SampleJavaProject.HibernateSession.HibernateUtil;
  
  /**
   * @author Siddhant_S
   * 
   */
  public class PersonBankApp {
      private static final Logger _logger = LoggerFactory
              .getLogger(PersonBankApp.class);
      private static final Session session = HibernateUtil.getSessionFactory()
              .openSession();
  
      /**
       * @return the Logger
       */
      public static Logger getLogger() {
          return _logger;
      }
  
      /**
       * @return the session
       */
      public static Session getSession() {
          return session;
      }
  
      /**
       * @param args
       */
      public static void main(String[] args) {
          getSession().beginTransaction();        
          Bank bank=new Bank("SBI", 2000.00);
          getSession().save(bank);
          Calendar birthDate=GregorianCalendar.getInstance();
          birthDate.setTime(new Date());
          Person person=new Person("Siddhant", 2000.00, birthDate, "lane4");
          PersonBankAssociation associations=new PersonBankAssociation("Sbi name", 2000.00);
          associations.setPerson(person);
          associations.setBank(bank);
          person.getBank().add(associations);
          Integer personId= (Integer) getSession().save(person);
          //getSession().save(associations);
          getSession().getTransaction().commit();
          getSession().close();
          System.out.println("Person id:"+personId);
      }
  
  }
  
  Error getting
  
  Hibernate: /* insert SampleJavaProject.Entity.Bank */ insert into test.Bank (amount, name) values (?, ?)
  Exception in thread "main" java.lang.NullPointerException
      at SampleJavaProject.Entity.PersonBankAssociation.setPerson(PersonBankAssociation.java:97)
      at SampleJavaProject.HibernateTransaction.PersonBankApp.main(PersonBankApp.java:57)
  </code></pre>