title: EclipseLink JPA Duplicate entry when persisting
body: <p>I have this strange error when trying to persist an annotated object. </p>
  
  <p>This is my code:</p>
  
  <pre><code>if (hashTags != null &amp;&amp; !hashTags.isEmpty()) {
      tweet.setHashTags(new LinkedList&lt;HashTag&gt;());
      for (HashTag hashTag : hashTags) {
          HashTag hashTagEntity = em
              .find(HashTag.class, hashTag.getTag());
          if (hashTagEntity == null) {
              LogWrapper.logger.debug("H: " + hashTag.getTag());
              em.persist(hashTag);
              tweet.getHashTags().add(hashTag);
          } else {
              tweet.getHashTags().add(hashTagEntity);
          }
      }
  }
  </code></pre>
  
  <p>I know that if you try to persist an existing object you get that exception but I do check that before calling the persist method. Also I can not find the primary key which cause the exception not in my log file nor in my MySQL database and it is confusing me how do I get an exception indicating a primary key value that does not exist in my database in first place.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>Those are my annotated classes where I show only the attributes and annotations:</p>
  
  <pre><code>@Entity
  public class Tweet {
  
      @Id
      @Column(name = "ID")
      private long id;
      private Usuario usuario;
      private String texto;
      @Temporal(TemporalType.TIMESTAMP)
      private Date fecha;
      private int numRetweets;
      @ManyToMany(fetch = FetchType.EAGER)
      @JoinTable(name = "TWEET_USUARIO_MENCIONADO", joinColumns = { @JoinColumn(name = "TWEET_ID", referencedColumnName = "ID") }, inverseJoinColumns = { @JoinColumn(name = "USUARIO_ID", referencedColumnName = "ID") })
      private LinkedList&lt;Usuario&gt; usuariosReferenciados;
      @ManyToMany(fetch = FetchType.EAGER)
      @JoinTable(name = "TWEET_HASHTAG", joinColumns = { @JoinColumn(name = "TWEET_ID", referencedColumnName = "ID") }, inverseJoinColumns = { @JoinColumn(name = "HASHTAG_ID", referencedColumnName = "ID") })
      private LinkedList&lt;HashTag&gt; hashTags;
      ...
  
  @Entity
  @Access(AccessType.FIELD)
  public class Usuario {
  
      @Id
      @Column(name = "ID")
      private long id;
      private String nombreEnPantalla;
      private int numTweets;
      @Temporal(TemporalType.TIMESTAMP)
      private Date fechaRegistro;
      @OneToMany(mappedBy = "usuario", fetch = FetchType.EAGER)
      private LinkedList&lt;Tweet&gt; tweets;
      private int numFollowers;
      private double tweetsPerDay;
      ...
  
  @Entity
  public class HashTag {
  
      @Id
      @Column(name = "ID")
      private String tag;
      ...
  </code></pre>
  
  <p>This is my entire method code where I have the problem:</p>
  
  <pre><code>    public Tweet crearTweet(long idTweet, Date fechaTweet, int numRetweets,
              String textoTweet, long idUsuario, Date fechaRegistroUsuario,
              int followersUsuario, String nombreEnPantallaUsuario,
              int numTweetsUsuario, List&lt;Usuario&gt; usuariosMencionados,
              List&lt;HashTag&gt; hashTags) {
          EntityManager em = emf.createEntityManager();
          em.getTransaction().begin();
          Tweet tweet = new Tweet();
          tweet.setFecha(fechaTweet);
          tweet.setId(idTweet);
          tweet.setNumRetweets(numRetweets);
          tweet.setTexto(textoTweet);
          em.persist(tweet);
          Usuario user = em.find(Usuario.class, idUsuario);
          if (user == null) {
              user = new Usuario();
              user.setFechaRegistro(fechaRegistroUsuario);
              user.setId(idUsuario);
              user.setNombreEnPantalla(nombreEnPantallaUsuario);
              user.setNumFollowers(followersUsuario);
              user.setNumTweets(numTweetsUsuario);
              em.persist(user);
          }
          tweet.setUsuario(user);
          if (usuariosMencionados != null &amp;&amp; !usuariosMencionados.isEmpty()) {
              tweet.setUsuariosReferenciados(new LinkedList&lt;Usuario&gt;());
              for (Usuario usuarioMencionado : usuariosMencionados) {
                  Usuario usuarioEntity = em.find(Usuario.class,
                          usuarioMencionado.getId());
                  if (usuarioEntity == null) {
                      LogWrapper.logger.debug("U: " + usuarioMencionado.getId()
                              + " " + usuarioMencionado.getNombreEnPantalla());
                      em.persist(usuarioMencionado);
                      tweet.getUsuariosReferenciados().add(usuarioMencionado);
                  } else {
                      tweet.getUsuariosReferenciados().add(usuarioEntity);
                  }
              }
          }
          if (hashTags != null &amp;&amp; !hashTags.isEmpty()) {
              tweet.setHashTags(new LinkedList&lt;HashTag&gt;());
              for (HashTag hashTag : hashTags) {
                  HashTag hashTagEntity = em
                          .find(HashTag.class, hashTag.getTag());
                  if (hashTagEntity == null) {
                      LogWrapper.logger.debug("H: " + hashTag.getTag());
                      em.persist(hashTag);
                      tweet.getHashTags().add(hashTag);
                  } else {
                      tweet.getHashTags().add(hashTagEntity);
                  }
              }
          }
          em.getTransaction().commit();
          em.close();
          return tweet;
      } 
  </code></pre>
  
  <p>And this is the entire stack-trace:</p>
  
  <pre><code>[EL Warning]: 2015-03-17 01:50:48.411--UnitOfWork(841203)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.DatabaseException
  Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '??' for key 'PRIMARY'
  Error Code: 1062
  Call: INSERT INTO HASHTAG (ID) VALUES (?)
      bind =&gt; [1 parameter bound]
  Query: InsertObjectQuery(um.es.TFG.modelo.HashTag@7a77e4)
  Exception in thread "main" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.DatabaseException
  Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '??' for key 'PRIMARY'
  Error Code: 1062
  Call: INSERT INTO HASHTAG (ID) VALUES (?)
      bind =&gt; [1 parameter bound]
  Query: InsertObjectQuery(um.es.TFG.modelo.HashTag@7a77e4)
      at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:159)
      at um.es.TFG.dao.jpa.JPATweetDAO.crearTweet(JPATweetDAO.java:76)
      at um.es.TFG.core.TweetProcessorMiner.startProcess(TweetProcessorMiner.java:105)
      at um.es.TFG.main.Main.main(Main.java:24)
  Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.DatabaseException
  Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '??' for key 'PRIMARY'
  Error Code: 1062
  Call: INSERT INTO HASHTAG (ID) VALUES (?)
      bind =&gt; [1 parameter bound]
  Query: InsertObjectQuery(um.es.TFG.modelo.HashTag@7a77e4)
      at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
      at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:902)
      at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:964)
      at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:633)
      at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:560)
      at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2055)
      at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:306)
      at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
      at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
      at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:377)
      at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:165)
      at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:180)
      at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:489)
      at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
      at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
      at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
      at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
      at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:904)
      at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:803)
      at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
      at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
      at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
      at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857)
      at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839)
      at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1790)
      at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:227)
      at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:194)
      at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:139)
      at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4260)
      at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
      at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
      at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:278)
      at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
      at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:134)
      ... 3 more
  Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '??' for key 'PRIMARY'
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
      at java.lang.reflect.Constructor.newInstance(Unknown Source)
      at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
      at com.mysql.jdbc.Util.getInstance(Util.java:360)
      at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:971)
      at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)
      at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
      at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
      at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
      at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2530)
      at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1907)
      at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2141)
      at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2077)
      at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2062)
      at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:892)
      ... 35 more
  </code></pre>
  
  <p><strong>Edit 2</strong></p>
  
  <p>If I do em.flush() after every persist operation and comment the following lines in my code, the error stops popping:</p>
  
  <pre><code>tweet.getUsuariosReferenciados().add(usuarioMencionado);
  tweet.getUsuariosReferenciados().add(usuarioEntity);
  tweet.getHashTags().add(hashTag);
  tweet.getHashTags().add(hashTagEntity);
  </code></pre>
  
  <p>I am commenting the above lines trying to do as little operations as possible to locate the problem and I already tried without commenting those lines and I still get the error if I do so, but as I said having them commented and flushing after every persist, my code run fine it just does not associate two more lists (HashTags and mentioned users ) of entities with my main entity (Tweet).
  So I know now that due to the many persists without flushing I am doing in one transaction I am getting the error but I don't know why it says duplicate key.</p>