2

I'm working with Spring Roo 1.2.3 on a project, and I need to create a new record of another entity X when the entity Stock is updated. I would do something like this (Similar to a trigger update in database).

@PostPersist
@PostUpdate
private void triggerStock() {
    Calendar fechaActual = Calendar.getInstance();      
    Long cantidad = this.getCantidadStock() - this.getCantidadAnterior();

    StockHistory history = new StockHistory();
    history.setArticulo(this.getArticulo());
    history.setFecha(fechaActual);
    history.setCantidad(cantidad);
    history.persist();      
}

When the application exits from this method throws an error and doesn't save the new element X.

But If I change the last method by:

@PostPersist
@PostUpdate
private void triggerStock() {
    Calendar fechaActual = Calendar.getInstance();      
    Long cantidad = this.getCantidadStock() - this.getCantidadAnterior();

    StockHistory history = new StockHistory();
    history.setArticulo(this.getArticulo());
    history.setFecha(fechaActual);
    history.setCantidad(cantidad);

    EntityManagerFactory emf = entityManager().getEntityManagerFactory();
    EntityManager em = emf.createEntityManager();   
    em.getTransaction().begin();
    em.setFlushMode(FlushModeType.COMMIT);      
    em.persist(history);
    em.getTransaction().commit();
    em.close();         
}

This works fine, but I'd like to understand Why I require a new EntityManager for this to work?

Thanks...

Hector
  • 691
  • 2
  • 14
  • 28

1 Answers1

1

PostUpdate is called during the commit, the persistence unit has already determined what changed and what it needs to write, so it is too late to change things (it would then need to recompute what it needs to write again).

Depending on what JPA provider you are using, there are some ways to force something to be written from an event, but you need to be careful.

James
  • 17,965
  • 11
  • 91
  • 146
  • In addition, I found the following information _β€œIn general, the lifecycle method of a portable application should not invoke EntityManager or Query operations, access other entity instances, or modify relationships within the same persistence context. A lifecycle callback method may modify the non-relationship state of the entity on which it is invoked.”_ http://www.theserverside.com/discussions/thread.tss?thread_id=61669 – Hector Jun 14 '13 at 15:58