title: Prevent duplicate entries in a join table in a many-to-many relationship in JPA
body: <p>I'm using EclipseLink 2.5.1 (and Hibernate 4.3.5 final). Given the following tables in MySQL.</p>
  
  <ul>
  <li>product</li>
  <li>prod_colour (join table)</li>
  <li>colour</li>
  </ul>
  
  <p>There is a many-to-many relationship between products and their colours.</p>
  
  <p>A product can have many colours and a colour can in turn be associated with many products. This relationship is expressed in the database by these tables.</p>
  
  <p>The <code>prod_colour</code> table has two reference columns <code>prod_id</code> and <code>colour_id</code> from its related parent tables <code>product</code> and <code>colour</code> respectively.</p>
  
  <p>As obvious, the entity class <code>Product</code> has a list of colours - <code>java.util.List&lt;Colour&gt;</code> which is named <code>colourList</code>.</p>
  
  <p>The entity class <code>Colour</code> has a list of products - <code>java.util.List&lt;Product&gt;</code> which is named <code>productList</code>.</p>
  
  <hr>
  
  <p>The relationship in the <code>Colour</code> entity : </p>
  
  <pre class="lang-java prettyprint-override"><code>public class Colour implements Serializable {
  
      @JoinTable(name = "prod_colour", joinColumns = {
          @JoinColumn(name = "colour_id", referencedColumnName = "prod_id")}, inverseJoinColumns = {
          @JoinColumn(name = "prod_id", referencedColumnName = "colour_id")})
      @ManyToMany(mappedBy = "colourList", fetch = FetchType.LAZY)
      private List&lt;Product&gt; productList; //Getter and setter.
  
      //---Utility methods---
  
      //Add rows to the prod_colour table.
      public void addToProduct(Product product) {
          this.getProductList().add(product);
          product.getColourList().add(this);
      }
  
      //Delete rows from the prod_colour table.
      public void removeFromProduct(Product product) {
          this.getProductList().remove(product);
          product.getColourList().remove(this);
      }
  }
  </code></pre>
  
  <p>The relationship in the <code>Product</code> entity :</p>
  
  <pre class="lang-java prettyprint-override"><code>public class Product implements Serializable {
  
      @JoinTable(name = "prod_colour", joinColumns = {
          @JoinColumn(name = "prod_id", referencedColumnName = "prod_id")}, inverseJoinColumns = {
          @JoinColumn(name = "colour_id", referencedColumnName = "colour_id")})
      @ManyToMany(fetch = FetchType.LAZY)
      private List&lt;Colour&gt; colourList; //Getter and setter.
  }
  </code></pre>
  
  <p>From the associated EJB, the insert operation is performed as follows.</p>
  
  <pre class="lang-java prettyprint-override"><code>@Override
  @SuppressWarnings("unchecked")
  public boolean insert(List&lt;Colour&gt; colours, Product product)
  {
      int i=0;
      Long prodId=product.getProdId();
      for(Colour colour:colours)
      {
          Product p = entityManager.getReference(Product.class, prodId);
          colour.addToProduct(p);
  
          if(++i%49==0)
          {
              entityManager.flush();
          }
          entityManager.merge(colour);
          entityManager.merge(p);
      }
      return true;
  }
  </code></pre>
  
  <p>Everything works fine.</p>
  
  <hr>
  
  <p>When duplicate rows are attempted (same <code>Colour</code> entities associated with the same <code>Product</code> entity), they are also inserted into the <code>prod_colour</code> table that I expect should not happen.</p>
  
  <p>Do I need to perform some extra conditional checks to avoid duplicate insertion or EclipseLink/Hibernate have some mechanism to prevent duplicates in such situations?</p>