title: JPA Hibernate: An entity copy [xxx] was already assigned to a different entity [yyyyy]
body: <p>Recently, when I use <strong>JPA(1.3.0.final)</strong> and <strong>Hibernate(4.2.6.final)</strong> on <strong>Play 2.2.1</strong> framework, I got errors like:</p>
  
  <p><strong>java.lang.IllegalStateException: Error occurred while storing entity [xxx] An entity copy [xxx] was already assigned to a different entity [yyy]</strong></p>
  
  <p>And none of the existing solutions on the Internet solves my prbolem.</p>
  
  <p>Now, let me explain a bit about the story.</p>
  
  <p>I have three entities, <strong>Owner</strong>, <strong>Box</strong>, and <strong>Item</strong>.</p>
  
  <p>Assumptions:</p>
  
  <ol>
  <li>An Item or a Box must have an Owner;</li>
  <li>A Box may contain zero or more Items, while an specific Item may not belong to any Box.</li>
  <li>When an Item is put into a Box, they may or may not have the same Owner.</li>
  </ol>
  
  <p>Entity Class:</p>
  
  <p>/* for simplicity, others fields, getter and setter are ommitted*/</p>
  
  <p>The simplified Owner class definition</p>
  
  <pre><code>    @Entity
      @Table(name = "OWNER")
      public class Owner implements Serializable{
          @Id
          @Column(name="ID")
          public String uuid = UUID.randomUUID().toString();
  
          @Override
          public int hashCode() {
              int result = 1;
              char[] charArray = this.uuid.toCharArray();
              int n = charArray.length;
              int powbase = (int) Math.pow(31, n - 1);
              for(int i = 0; i &lt; n; i++){
                  if ( i != 0){
                  powbase = powbase / 31;
                  }
                  result += (int)charArray[i] * powbase;
              }
              return result;
          }
  
          @Override
          public boolean equals(Object obj) {
              if(obj == null){
                  return false;
              }
              if(!(obj instanceof Item)){
                  return false;
              }
              Item other = (Item)obj;
              //Box other = (Box)obj;
              //Owner other = (Owner)obj;
              if(!other.uuid.equals(this.uuid)){
                  return false;
              }
              return true;
          }
  }
  </code></pre>
  
  <p>The implementation of hashCode() and equals() of Item and Box are similar to Owner. For sake of argument, let's omit these.</p>
  
  <p>The simplified Item class definition</p>
  
  <pre><code>@Entity
  @Table(name = "ITEM")
  public class Item implements Serializable{
  
      @Id
      @Column(name="ID")
      public String uuid = UUID.randomUUID().toString();
  
      /* single-directional mapping*/
      @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = false)
      @JoinColumn(name = "O_ID")
      public Owner owner;
  
      /* bi-directional mapping*/
      @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH })
      @JoinColumn(name = "B_ID")
      public Box box;
  }
  </code></pre>
  
  <p>The simplified Box class definition.</p>
  
  <pre><code>@Entity
  @Table(name = "BOX")
  public class Box implements Serializable {
  
      @Id
      @Column(name="ID")
      public String uuid = UUID.randomUUID().toString();
  
      /* single-directional mapping*/
      @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = false)
      @JoinColumn(name = "O_ID")
      public Owner owner;
  
      /* bi-directional mapping*/
      @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH,
              CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER, mappedBy = "box")
      public Set&lt;Item&gt; items = new HashSet&lt;Item&gt;();
  }
  </code></pre>
  
  <p>The business logic is shown as follows:</p>
  
  <pre><code>public class Test {
  
      public static void main(String[] args) {
          Owner owner = new Owner();
          JPA.em().persist(owner);
  
          Box box = new Box();
          box.owner = owner;
          JPA.em().persist(box);
  
          Item boxItem = new Item();
          boxItem.owner = owner;
          boxItem.box = box;
          box.items.add(boxItem);
          JPA.em().persist(boxItem);
  
          Item nonBoxItem = new Item();
          nonBoxItem.owner = owner;
          JPA.em().persist(nonBoxItem);
  
          /* in the future, put the 'nonBoxItem' into a box*/
          Item itemToUpdate = JPA.em().find(Item.class, nonBoxItem.uuid);
          itemToUpdate.box = box;
          box.items.add(itemToUpdate);
  
          JPA.em().merge(itemToUpdate); /* error occurred here*/
      }
  
  }
  </code></pre>
  
  <p>Does anyone have any idea to solve this problem? </p>
  
  <p>Thanks.</p>