title: Multiple representations of the same entity are being merged JPA
body: <p>Schema definition</p>
  
  <pre><code>CREATE TABLE person (
    id bigint(20) NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
  ) ENGINE=InnoDB
  
  CREATE TABLE address (
      person_id bigint(20) not null,
      postcode varchar(255) not null,
      state int(11),
      constraint `PRIMARY` primary key (address_id, postcode),
      constraint FK_dq8j32idfdnwny42fiovenqwo foreign key (person_id) references person (id)
  ) ENGINE=InnoDB
  </code></pre>
  
  <p>Ie a person should be able to have multiple addresses as long as the postcode is different.</p>
  
  <p>Classes</p>
  
  <pre><code>@Entity
  @Getter
  @Setter
  class Person implements Serializable {
      @Id
      @GeneratedValue(strategy=GenerationType.AUTO)
      @Column(name="id", unique = true, nullable = false)
      private Long id;
  
      @OneToMany(cascade= CascadeType.ALL)
      private Set&lt;Address&gt; Addresses = new HashSet&lt;&gt;();
  
      protected Person(){}
  }
  
  @Entity
  @Getter
  @Setter
  class Address implements Serializable {
      @EmbeddedId
      private AddressId addressId;
      private State state;
      protected Address(){}
  }
  
  @Embeddable
  @Getter
  @Setter
  public class AddressId implements Serializable {
      @Column(name = "person_id")
      private Long personId;
      @Column(name = "postcode")
      private String postcode;
  }
  </code></pre>
  
  <p>This works in the sense that it allows adding more than one address to the same person as long as the two addresses have different postcodes. </p>
  
  <pre><code>Person person = personRepo.findOne(personId);
  
  AddressId addressId = new AddressId();
  addressId.setPersonId(personId);
  addressId.setPostcode("4000");
  Address address = new Address();
  address.setAddressId(addressId);
  address.setState(State.QLD);
  person.getAddresses().add(address);
  
  AddressId addressId2 = new AddressId();
  addressId2.setPersonId(personId);
  addressId2.setPostcode("4001");
  Address address2 = new Address();
  address2.setAddressId(addressId2);
  address.setState(State.VIC);
  person.getAddresses().add(address2);
  
  person = personRepo.save(person);
  </code></pre>
  
  <p>But when trying to update one of them (eg changing the state)</p>
  
  <pre><code>Person person = personRepo.findOne(personId);
  
  AddressId addressId = new AddressId();
  addressId.setPersonId(personId);
  addressId.setPostcode("4000"); //person already has an address with this postcode
  Address address = new Address();
  address.setAddressId(addressId);
  address.setState(State.TAS); //but I want to change the state from QLD to TAS
  person.getAddresses().add(address);
  person = personRepo.save(person);
  </code></pre>
  
  <p>the below is generated. I think the below basically means "Hey, you're trying to add an address with a person_id and postcode that already exists, I don't care if the state is different, you can't do that". How can it be made to work?</p>
  
  <blockquote>
    <p>Caused by: java.lang.IllegalStateException: Multiple representations
    of the same entity [Address#AddressId@5047ce78] are being merged.
    Managed: [Address@5c220478]; Detached: [Address@79804699]     at
    org.hibernate.event.internal.EntityCopyNotAllowedObserver.entityCopyDetected(EntityCopyNotAllowedObserver.java:51)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.event.internal.MergeContext.put(MergeContext.java:262)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.event.internal.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:216)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:192)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:886)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.internal.SessionImpl.merge(SessionImpl.java:868)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:277)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:474)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.event.internal.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:218)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:192)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
    ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]   at
    org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
    ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]  at
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    ~[na:1.8.0_102]   at
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    ~[na:1.8.0_102]   at
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    ~[na:1.8.0_102]   at java.lang.reflect.Method.invoke(Method.java:498)
    ~[na:1.8.0_102]</p>
  </blockquote>
  
  <p>However, if I do</p>
  
  <pre><code>Person person = personRepo.findOne(personId);
  new ArrayList&lt;&gt;(person.getAddresses()).get(0).setState(State.QLD); //change state of existing address row
  person = personRepo.save(person);
  </code></pre>
  
  <p>I don't get the exception. I think Hibernate detects that in that case, an existing row is being updated, whereas if trying to ADD another Address with the same personId and postcode as one that already exists, it tries to do an INSERT and fails. Is there no way to make Hibernate figure out to do an update in date case as well?</p>