title: Duplicate key value violates unique constraint for primary key
body: <p>I have a problem where I get <code>duplicate key value violates unique constraint "my_obj_pk"</code>.
  Where <code>my_obj_pk</code> is a primary key of a table mapped to Spring entity and based on <code>id</code>:</p>
  
  <pre><code>@Entity
  @Table(name = "MY_TABLE")
  @SequenceGenerator(name = "MY_OBJ_SEQ", allocationSize = 500)
  public class MyObject {
  
     @Id
     @GeneratedValue(generator = "MY_OBJ_SEQ", strategy = GenerationType.TABLE)
     private Long id;
  ...
  }
  </code></pre>
  
  <p>The exception is:</p>
  
  <pre><code>Internal Exception: java.sql.BatchUpdateException: Batch entry 1 INSERT INTO MY_TABLE (ID, ...) VALUES (257521, ...) was aborted: ERROR: duplicate key value violates unique constraint "my_obj_pk"
    Detail: Key (id)=(257521) already exists.  Call getNextException to see other errors in the batch.
  Error Code: 0
  Call: INSERT INTO MY_TABLE (ID, ...) VALUES (?, ...)
      bind =&gt; [8 parameters bound]
      at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:524)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
      at com.sun.proxy.$Proxy341.saveMyObject(Unknown Source)
      at MyWorker.doWork(MyWorker.java:172)
      at java.util.concurrent.CompletableFuture$AsyncRun.run$$$capture(CompletableFuture.java:1626)
      ... 4 more
  Caused by: javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.3.v20180807-4be1041): org.eclipse.persistence.exceptions.DatabaseException
  Internal Exception: java.sql.BatchUpdateException: Batch entry 1 INSERT INTO MY_TABLE (ID, ...) VALUES (257521, ...) was aborted: ERROR: duplicate key value violates unique constraint "my_obj_pk"
    Detail: Key (id)=(257521) already exists.  Call getNextException to see other errors in the batch.
  Error Code: 0
  </code></pre>
  
  <p>As you may see the JPA implementation is <code>Eclipse Persistence Services - 2.7.3.v20180807-4be1041</code>. The DB is PostgreSQl 9.4.0.</p>
  
  <p><code>MyWorker</code> is a Spring Component, that once in 10 minutes spawns 35 <code>CompletableFuture</code> objects that are run via executor having 20 threads. Each such <code>Future</code> multiple times calls various functions from 
  Spring Service <code>MyServiceImpl</code>, where each function in the service is annotated with <code>Transactional</code> and <code>PermitAll</code>. These functions pull via different <code>Repository</code> various objects, say <code>X</code> and <code>Collection&lt;Y&gt;</code>,
  part of these objects are created, if not exist already, however, not saved explicitly. </p>
  
  <p><code>X</code> has the following:</p>
  
  <pre><code>@OneToMany(mappedBy = "xObj", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
  List&lt;MyObject&gt; myObjects;
  </code></pre>
  
  <p><code>Y</code> has the following:</p>
  
  <pre><code>@OneToMany(mappedBy = "yObj", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
  List&lt;MyObject&gt; myObjects;
  </code></pre>
  
  <p><code>MyObject</code> has:</p>
  
  <pre><code>@ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "X_ID")
  private X xObj;
  
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "Y_ID")
  private Y yObj;
  </code></pre>
  
  <p>So, basically, <code>X</code> and <code>Y</code> have a list of <code>MyObject</code> that have <code>X</code> and <code>Y</code> inside</p>
  
  <p>At the end each <code>Future</code> calls <code>saveMyObject()</code> with <code>X</code> and <code>Collection&lt;Y&gt;</code> from the same <code>MyServiceImpl</code>:</p>
  
  <pre><code>@Override
  @PermitAll
  @Transactional
  public void saveMyObject(X x, Collection&lt;Y&gt; colY) {
      xRepository.save(x);
      yRepository.save(colY);
      final List&lt;MyObject&gt; myObjects = x.getMyObjects() == null ?
              new ArrayList&lt;&gt;(colY.size()) : x.getMyObjects();
      colY.forEach(p -&gt; {
          MyObject o = new MyObject();
          myObjects.add(o);
          List&lt;MyObject&gt; pobj = p.getMyObjects();
          if (pobj == null) {
             pobj = new ArrayList&lt;&gt;();
             p.setMyObjects(pobj);
          }
          pobj.add(o);
      });
      x.setMyObjects(myObjects);
      myObjectsRepository.save(myObjects);
  }
  </code></pre>
  
  <p>There is NO manual assignment of IDs anywhere...
  As of now, I don't get how the PK of MyObject may be duplicated. I prefer, if possible, not to touch <code>CASCADE</code> properties, as these classes exist for a long time
  and are used widely. Thanks!</p>
  
  <p>Edit: I should add that different <code>Future</code> may work on the same <code>Y</code> and <code>MyObject</code> , so, probably, the design is not quite right</p>