How to invoke callback methods like @PreUpdate, @PrePersist, @PreRemove while doing bulk update, delete, insert in JPA 2.1?

StackOverflow https://stackoverflow.com//questions/24000983

Question

How to call a method annotated by @PreUpdate (including @PrePersist, @PreRemove and others) in JPA 2.1? Given the following CriteriaUpdate query as an example:

Brand brand=//... Populated by client. The client is JSF in this case.
byte[] bytes=//... Populated by client. The client is JSF in this case.

CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaUpdate<Brand>criteriaUpdate=criteriaBuilder.createCriteriaUpdate(Brand.class);
Root<Brand> root = criteriaUpdate.from(entityManager.getMetamodel().entity(Brand.class));

criteriaUpdate.set(root.get(Brand_.brandName), brand.getBrandName());
criteriaUpdate.set(root.get(Brand_.category), brand.getCategory());
criteriaUpdate.set(root.get(Brand_.brandImage), bytes);
criteriaUpdate.where(criteriaBuilder.equal(root, brand));
entityManager.createQuery(criteriaUpdate).executeUpdate();

Given the method decorated by @PreUpdate in the associated entity - Brand.

@Column(name = "last_modified")
@Temporal(TemporalType.TIMESTAMP)
private Date lastModified;  //Getter and setter.


@PreUpdate
public void onUpdate() {
    lastModified = new Date();
    System.out.println("lastModified = "+lastModified);
}

This method is only invoked, when a row is updated using

entityManager.merge(brand);

How to invoke a method decorated by @PreUpdate (or @PrePersist, @PreRemove), when relevant operations involve the criteria API like CriteraUpdate?

Was it helpful?

Solution

You're not passing the entity to JPA. You're merely extracting the individual entity properties and passing them to JPA. In order to get the entity's @PreUpdate and friends invoked by JPA, you need to pass the whole entity to JPA, like as usual with EntityManager#merge().

If that's not an option for some unclear reason (perhaps the entity is way too large and you'd like to skip unnecessary properties from being updated? in such case, consider splitting the entity over smaller @OneToOne relationships), then you'd need to manually invoke those methods on the entity before extracting and passing the entity's properties to JPA.

Brand brand = ...
brand.onUpdate();
byte[] bytes = ...

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
// ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top