Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating one field in JPA entity

Tags:

jpa

I have an Entity User that is assigned a system privilege in a function. I have a web page where you select a user from a drop down and submit the form to the server. On the server side I want to update only one field for that entity.

My User entity will have default values for all objects except the one field that gets set and its id. Do I need to do a findById then update the specific field then do the merge or is there a way to tell the to only update that field?

like image 204
Allan Avatar asked Aug 13 '10 12:08

Allan


2 Answers

Do I need to do a findById then update the specific field then do the merge

That would be the regular approach, except that you don't need to merge a managed entity, just let JPA detect the changes and update it automatically.

or is there a way to tell the to only update that field?

No. But you could use a "short" version of your User (with only the field(s) to update). Another option would be to use a Bulk Update Operation but this is IMO really not a good use case. I wouldn't use this approach.

Reference

  • JPA 1.0 specification
    • 4.10 Bulk Update and Delete Operations
like image 109
Pascal Thivent Avatar answered Nov 12 '22 04:11

Pascal Thivent


JPA 2.1 now support update criteria that allow you to partial update entity via javax.persistence.criteria.CriteriaUpdate<T>.

Javadoc here.

Example code:

EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();

// create user
em.getTransaction().begin();
User user = new User();
user.setUsername("[email protected]");
user.setPassword("password");
user.setCreatedAt(new Date());
em.persist(user);
em.getTransaction().commit();
// end create user

assert user.getId() != 0;

System.out.println("Before update user Date of Birth: " + user.getDateOfBirth());

// update user date of birth
em.getTransaction().begin();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaUpdate<User> updateCriteria = cb.createCriteriaUpdate(User.class);
Root<User> root = updateCriteria.from(User.class);
// update dateOfBirth property
updateCriteria.set(root.get("dateOfBirth"), new Date());
// set where clause
updateCriteria.where(cb.equal(root.get("id"), user.getId()));
// update
int affected = em.createQuery(updateCriteria).executeUpdate();
System.out.println("Affected row: " + affected);
em.getTransaction().commit();
// end update user date of birth


// select user again to verify
em.getTransaction().begin();
em.refresh(user);

System.out.println("After update User Date of Birth: " + user.getDateOfBirth());

em.getTransaction().commit();
em.close();

More details on JPA 2.1 partial update here.

like image 44
Pau Kiat Wee Avatar answered Nov 12 '22 03:11

Pau Kiat Wee