title: Hibernate error persists an entity in @PostPersist method
body: <p>I have a weird error of double insert in the DB. I have the following classes:</p>
  
  <ul>
  <li>TestEntity - entity with a @PrePersist and a @PostPersist methods.</li>
  <li>Auditoria - audit entity</li>
  <li>Dataset - interface of DatasetBean</li>
  <li>DatasetBean - Stateless bean which implements Dataset</li>
  <li>DatasetFactory - instance an EJB of Dataset (lookup)</li>
  </ul>
  
  <p>I put the problem in a junit test (I'm using embedded Glassfish):</p>
  
  <pre><code>@Test
  public void test() throws NamingException {
      Dataset&lt;TestEntity&gt; dataset = this.lookupBy(DatasetBean.class);
      Assert.assertNotNull(dataset);
  
      TestEntity t = new TestEntity();        
      t.setName(UUID.randomUUID().toString());
  
      dataset.insert(t);
      System.out.println("end");
  }
  </code></pre>
  
  <p>The flow of the test is the following:</p>
  
  <ol>
  <li><p>After gettin a Dataset object, I try to insert a TestEntity object</p>
  
  <p>@Stateless
  @EJB(name = "...", beanInterface = Dataset.class)
  public class DatasetBean implements Dataset {</p>
  
  <pre><code>@PersistenceContext(type = PersistenceContextType.TRANSACTION)
  private EntityManager entityManager;
  
  @Override
  public void insert(T entidade) {
      LOG.info("Inserting: " + entidade);
      entityManager.persist(entidade);
  }
  //...
  </code></pre>
  
  <p>}</p></li>
  <li><p>Using the DatasetFactory, I try to insert an Auditing entity in a @PostPersist method of the TestEntity</p>
  
  <p>public class DatasetFactory {
      public static Dataset createDataset() {
          try {
              return (Dataset) new InitialContext().lookup("...");
          } catch (Exception ex) {
              throw new RuntimeException(ex);
          }
      }
  }</p>
  
  <p>@Entity
  public class TestEntity implements MyEntity {
      @Id
      private Integer id;
      private String name;
      // sets and gets   </p>
  
  <pre><code>@PrePersist
  public void fillId() {
      if (getId() == null || getId() == 0) {
          Dataset d = DatasetFactory.createDataset();
          Integer i = (Integer) d.fetchJPQLFirstResult("SELECT MAX(te.id) FROM TestEntity te");
          if (i == null || i &lt; 100) {
              setId(100);
          } else {
              setId(i + 1);
          }
      }
  }  
  
  @PostPersist
  public void audit() {
      Dataset&lt;Auditing&gt; dataset = DatasetFactory.createDataset();
      // dataset.getEntityManager().clear();
      Auditing auditing = new Auditing();
      auditing.setIdEntidade(String.valueOf(this.getId()));
      dataset.insert(auditing);
  }
  </code></pre>
  
  <p>}</p>
  
  <p>@Entity
  public class Auditoria implements MyEntity {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Integer id;
      private String idEntity;
      //sets and gets
  }</p>
  
  <p>public interface MyEntity extends Serializable {
      Integer getId();
  }</p></li>
  </ol>
  
  <p><strong>Log:</strong></p>
  
  <p>INFO: embedded was successfully deployed in 47.154 milliseconds.
  PlainTextActionReporterSUCCESSDescription: deploy AdminCommandApplication deployed with name embedded.</p>
  
  <p>2012-01-06 02:56:54,826 [main] INFO  com.joaosavio.model.db.DatasetBean (DatasetBean.java:30) - Inserting: TestEntity{id=null, name=ea5c2af4-0ca7-48a2-a82a-dbf582c570a9}</p>
  
  <p>Hibernate: select max(testentity0_.id) as col_0_0_ from TestEntity testentity0_</p>
  
  <p><strong>Hibernate: insert into TestEntity (name, id) values (?, ?)</strong></p>
  
  <p>2012-01-06 02:56:56,344 [main] INFO  com.joaosavio.model.db.DatasetBean (DatasetBean.java:30) - Inserting: Auditoria{id=null, idEntidade=100}</p>
  
  <p><strong>Hibernate: insert into TestEntity (name, id) values (?, ?)</strong></p>
  
  <p>2012-01-06 02:56:56,350 [main] WARN  org.hibernate.engine.jdbc.spi.SqlExceptionHelper (SqlExceptionHelper.java:143) - SQL Error: 2627, SQLState: 23000</p>
  
  <p>2012-01-06 02:56:56,352 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper (SqlExceptionHelper.java:144) - Violation of PRIMARY KEY constraint 'PK_<em>TestEntity</em>_76818E95'. Cannot insert duplicate key in object 'dbo.TestEntity'.</p>
  
  <p>06/01/2012 02:56:56 com.sun.ejb.containers.BaseContainer postInvoke</p>
  
  <p>WARN: A system exception occurred during an invocation on EJB DatasetBean method public void com.joaosavio.model.db.DatasetBean.insert(java.lang.Object)
  javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
  ...</p>
  
  <p>Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Violation of PRIMARY KEY constraint 'PK_<em>TestEntity</em>_76818E95'. Cannot insert duplicate key in object 'dbo.TestEntity'.
  ...</p>
  
  <p>Caused by: org.hibernate.exception.ConstraintViolationException: Violation of PRIMARY KEY constraint 'PK_<em>TestEntity</em>_76818E95'. Cannot insert duplicate key in object 'dbo.TestEntity'.</p>
  
  <p><strong>Considerations:</strong></p>
  
  <p>Relying on the fact that everything works fine if I clear the entity manager before the insertion of the Auditing entity (comented code in @PostPersist method in TestEntity), I believe that the TestEntity is getting stuck in the transaction.</p>
  
  <p>What am I doing wrong???</p>