0

I would like to do a simple update on a managed JPA entity on many fields. First I query the entity which I would like to update:

MyEntity managedEntity = entityManager.createQuery(query).getSingleResult();

Then I need to update this entity with a new "MyEntity" object which is not managed by JPA:

MyEntity notManagedEntity = new MyEntity();

Of course it would be possible to read each field from notManagedEntity and set them to managedEntity which would do the update.

But is there a more elagant way to update the managed entity without needing to get and set every field one by one?

clementino
  • 287
  • 1
  • 12
  • `Then I need to update this entity with a new "MyEntity" object which is not managed by JPA` any reason for this? – XtremeBaumer Mar 26 '18 at 13:26
  • Did you try setting the id field on `notManagedEntity` to the id of `managedEntity` then calling `update` on `notManagedEntity`? – Yserbius Mar 26 '18 at 13:30
  • what @Yserbius is saying is that You don't need to get and set every field. You only need do that for the primary key or id field. This cannot be avoided. – jaletechs Mar 26 '18 at 13:36
  • @XtremeBaumer because "notManagedEntity" has to be created and mapped from a csv, and then persisted to the database. However if notManagedEntity.equals(managedEntity) jpa should do an update. The "equals" method is already set up properly, and does not depend on the primary key. – clementino Mar 26 '18 at 13:39
  • @AdamsonJeremiah but "notManagedEntity" doesn't have any id (primary key) at that moment as it wasn't yet persisted. However the equality of the 2 objects is implemented for an other field which is not the primary key. Is this a problem? – clementino Mar 26 '18 at 13:43
  • `Hibernate` offers the method `saveOrUpdate` which is most probalby what you are looking for – XtremeBaumer Mar 26 '18 at 13:51
  • @clementino Does the equals method use all the other variables except id field or only subset of them? Posting the `MyEntity` class would help. – Madhusudana Reddy Sunnapu Mar 26 '18 at 13:55
  • @clementino naturally, equality should be implemented on the field which helps the entity to be unique. I can't think of a situation where I would implement equality with a non-unique field. And if said field is unique, then it becomes a strong candidate for being a primary key. Nevertheless, if uniqueness is guaranteed, a simple test would show if the said entity is the same. But you might still have to map the fields with getters and setters. – jaletechs Mar 26 '18 at 13:55
  • @XtremeBaumer I suppose you mean if he is calling Hibernate specific methods and not JPA methods? – jaletechs Mar 26 '18 at 13:57
  • Since the question is flagged with `Hibernate`, yes – XtremeBaumer Mar 26 '18 at 14:02
  • @MadhusudanaReddySunnapu the equals is implemented on a field which is guaranteed to be unique, but it's still not the primary key. Due to some enviromental restrictions I can't change this unfortunately. As I already see, there will be not really a straightforward solution for this except of mapping the fields one by one. – clementino Mar 26 '18 at 14:05
  • 1
    If the intent is only to eliminate manual copying of fields from `notManagedEntity` to `managedEntity`, you can look at https://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/BeanUtils.html#copyProperties-java.lang.Object-java.lang.Object- It takes care of populating the fields automatically. – Madhusudana Reddy Sunnapu Mar 26 '18 at 14:12
  • @MadhusudanaReddySunnapu thanks, I'll try this. However I was curious if Hibernate has some similar built-in functionality, so it could be avoided to include third-party library. – clementino Mar 26 '18 at 14:21
  • I doubt if hibernate has anything that suits your requirement exactly – Madhusudana Reddy Sunnapu Mar 26 '18 at 14:25

2 Answers2

0

AFAIK, it's not a good idea to change a reference to a managed entity, because the persistence context will still reference the old entity, so any flush would trigger an exception... It's even more important when working with complex entities holding collections or ManyToOne references.

A related topic: What is the best way to update the entity in JPA

HBo
  • 495
  • 4
  • 14
  • Thanks, the answer suggests here to set the properties to be updated, and let JPA do the update. This is what I wanted to avoid, as I need to update like 30 properties, and my question was if there is a "better" way to do this.But if not, I will go this way. – clementino Mar 26 '18 at 13:50
  • Absolutely. I ended up building a tool to do it from DTO objects, because that's the only way I found to avoid any kind of PersistenceException or equivalent, especially for large or complex objects... – HBo Mar 26 '18 at 13:53
0

I would suggest to read the question: Copy all values from fields in one class to another through reflection

This looks like the answer to your question. You then have to create a copy of the entiy you got from

MyEntity managedEntity = entityManager.createQuery(query).getSingleResult();

After you created the copy of you java object, you have to set the identifier from the entity an new value an inset this new Object to the persistent layer again.

From desinge perpective it looks a bit confusing, but if this is the request, at least from technical perspective it should work.

Repi
  • 68
  • 4