Entitylisteners @Transactional Demoiselle - Id null

Asked

Viewed 86 times

1

I’m setting up audit on a project with JSF + Hibernate + Demoiselle.

Item class:

@Entity
@Cacheable(true)
@Table(name = "itens")
@EntityListeners(value = PersistenceAuditor.class)
@XmlRootElement
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Item {
   private static final long serialVersionUID = 1L;
   @Id
   GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private Long id;
   @LazyCollection(LazyCollectionOption.FALSE)
   @OneToMany(mappedBy = "item", orphanRemoval = true, cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
   @JsonManagedReference(value="itemParam")
   private List<ItemParam> params;

Itemparam class:

@Entity
@Cacheable(true)
@Table(name = "item_params")
@EntityListeners(value = PersistenceAuditor.class)
@XmlRootElement
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ItemParam {
   private static final long serialVersionUID = 1L;
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private Long id;
   @NotNull
   @ManyToOne
   @JoinColumn(name = "item_id", referencedColumnName = "id", nullable = false)
   @JsonBackReference(value="itemParam")
   private Item item;

In the Persistenceauditor:

@PostPersist
public void postPersist(Object object) {
... consome auditoria

And to record:

@Transactional    
public String insert() {
   this.itemBC.insert(this.getBean());
   return getPreviousView();
}

Itembc

@BusinessController
public class ItemBC extends DelegateCrudExt<Item, Long, ItemDAO> {

The audit is persisted but with the objects with id null as if taking the object before being "commited" and I would like the object already updated. Perhaps because of the @Transactional.

Output from the object:

Item{"id":69,"params":[{"id":null,"valor":10.0"}]}
ItemParam{"id":3,"valor":10.0}

Where it should be something like:

Item{"id":69,"params":[{"id": 3,"valor":10.0"}]}
ItemParam{"id":3, "item":69, "valor":10.0}

Any ideas on how to fix this?

  • Is there any way to put the code for this.itemBC.Insert(this.getBean()) function? A full Item class would also help a lot!

  • Itembc Insert uses the direct Insert of Demoiselle but I posted it and also the item class and the daughter class (Itemparam)

1 answer

1


According to the JSR 338 specification (Java Persistence API, Version 2.1) on page 101:

It is implementation-dependent as to whether callback methods are Invoked before or after the Cascading of the Lifecycle Events to Related entities. Applications should not Depend on this Ordering.

Basically this means that the postPersist method of the item can be called before the itemParam is persisted.

If the methods are executed in this order, the desired behavior would be obtained:

  • persist Item
  • persist Itemparam
  • postPersist of the Item
  • postPersist of the Itemparam

But execution can also happen in this order:

  • persist Item
  • postPersist of the Item
  • persist Itemparam
  • postPersist of the Itemparam

If they are executed in this order, notice that itemParam will have id null in the Item postPersist, since the itemParam persist has not yet been called.

According to the jpa specification the implementor (Hibernate) can execute the methods in either of the two orders, so your code has to be made to function independent of the order that Hibernate decided to choose.

I think it’s best not to use postPersist in this case. A solution would be to make a function in the Itemdao that calls the persist in the Item (that will give persist in the cascade params) and then consumes the audit (and everything will already be with correct id since the persist of the params already generated the ids).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.