title: java.sql.SQLIntegrityConstraintViolationException when updating an entity
body: <p>I am new to JPA and I am experiencing the following problem, probably due to a not sufficient understanding of cascade and associations? 
  I have two entities which are in a bidirectional OneToMany - ManyToOne association:</p>
  
  <pre><code>@Entity
  public class TestRun implements Serializable {
  
      private static final long serialVersionUID = 1L;
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
  
      public Long getId() {
          return id;
      }
  
      public TestRun(){
  
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      @ManyToOne(optional=false, cascade={CascadeType.PERSIST, CascadeType.MERGE})
      private Test performedTest;
  
      public Test getPerformedTest() {
          return performedTest;
      }
  
      public void setPerformedTest(Test performedTest) {
          this.performedTest = performedTest;
      }
      .....
  
      @Override
      public boolean equals(Object object) {
          if (!(object instanceof TestRun)) {
              return false;
          }
          TestRun other = (TestRun) object;
          if ((this.id == null &amp;&amp; other.id != null) || (this.id != null &amp;&amp; !this.id.equals(other.id))) {
              return false;
          }
          return true;
      }
  
      @Override
      public String toString() {
          return "TestRun[ id=" + id + " ]";
      }
  }
  </code></pre>
  
  <p>And: </p>
  
  <pre><code>  @Entity
      public class Test implements Serializable {
          private static final long serialVersionUID = 1L;
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          private Integer id;
  
          @Basic(optional=false) 
          @Column(nullable=false)
           private String name;
  
          @OneToMany(mappedBy="performedTest", cascade={CascadeType.MERGE, CascadeType.PERSIST})
          private Collection&lt;TestRun&gt; appearsOnTestRuns;
  
          public Collection&lt;TestRun&gt; getAppearsOnTestRuns() {
              return appearsOnTestRuns;
          }
  
          public void setAppearsOnTestRuns(Collection&lt;TestRun&gt; appearsOnTestRuns) {
              this.appearsOnTestRuns = appearsOnTestRuns;
          }
          //id based equals and hashcode
      ...
      }
  </code></pre>
  
  <p>The relationship means that I have a set of Test-s which are perfomed several times, each time being associated with a TestRun. 
  To create a TestRun, I use the following method:</p>
  
  <pre><code>public void createTestRun(String name){
      Test testPerformed = ejb.findByName(name); //Returns null iff forTest is not in the DB--&gt; INSERT new Test
      if (testPerformed == null){
          testPerformed = EntityFactory.newTest(name);//I set the name for test
      }
      TestRun run = EntityFactory.newTestRun(testPerformed);
      ejb.persist(run);
  }
  
  public class EntityFactory{
      public static TestRun newTestRun(Test test){
          TestRun run = new TestRun();
          run.setPerformedTest(test);
          return run;
      }
      public static Test newTest(String name){
          Test test = new Test();
          test.setName(name);
          return test;
      }
  }
  </code></pre>
  
  <p>when createTestRun deals with a new Test (insert), the Test object is correctly persisted as well as the TestRun. But when the test already exists, JPA (EclipseLink in my case) tries anyway to execute an INSERT:</p>
  
  <pre><code>....
  Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
  Internal Exception: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL110705102925930' defined on 'TEST'.
  Error Code: -1
  Call: INSERT INTO TEST (ID, NAME) VALUES (?, ?)
  </code></pre>
  
  <p>What does it happen behind the scenes? Does the problem have to do with the appearsOnTestRuns property of Test? Why doesn't JPA understand that Test already exists in the DB (after all, the id property is set during the find operation and equals() uses this value to decide whether 2 Tests are equal..)
  Thanks a lot for your help! :)</p>
  
  <p>PS: Do you know a good tutorial / book where these concepts are extensively explained?</p>