Difference between Merge() and getInstace() in JPA/Hibernate

Asked

Viewed 1,339 times

2

I wonder when I should use merge() to update the object instead of changing it through its reference.

Example:

Produto p = new Produto();
p.setNome("Bola");
p.setvalor("32);
manager.persist(p);
manager.getTransation().begin();
manager.getTransation().commit();

Updating with merge()

Produto p2 = p;
p2.setNome("Bola Editado");
manager.merge(p2);
manager.getTransation().commit();

Updating with getInstance()

Produto p2 = manager.getReference(Produto.class, p.getId());
p2.setNome("Bola Editado")
manager.getTransation().begin();
manager.getTransation().commit();

1 answer

2


TL;DR

The merge() receives a "common" object, which is not in the persistence context, and copies the properties of this object to the true instance of the entity. Use it when you do not want to retrieve the entity and change its attributes manually.

Objects vs. Entities and the functioning of JPA

The first step to better understand how JPA works is to understand exactly how it treats the entities and states that these objects can assume.

For that, I suggest you read my other answer on the subject.

Using the merge

Basically, the merge() receives an object created outside of JPA, either directly in your code or in some automatic process like some JSON deserializer or an MVC framework that maps the request for a Java Bean.

Upon receiving this object, JPA checks whether an instance already exists in the context or retrieves one from the database.

Then it takes the values of the instance you passed and assigns it to the instance of the persistence context, effectively updating the data of the true entity. Note that it will update all attributes and not only those that have value.

So the method merge() returns to you the updated entity. At this point, the object you passed to it can be discarded.

When to use the getReference()

The getReference() returns a proxy to an entity that is in the database. The data is not loaded from the database immediately, other than the primary key. This proxy works like an object Lazy which will only load the attributes of the entity when you call some method getter.

Anyway, use this method when you want to avoid loading too much data from the database unnecessarily, as in cases where you will only use one or two fields of an entity only if a certain condition is met or when you need to pass an entity as a parameter and possibly it is not used within the receiving method.

Anyway, the advantage is to postpone data transfer that you probably won’t use. The disadvantage is that if you use the data, the "cost" is higher since you will have to make more queries to the bank.

Honestly, I’ve never seen a real need to use this method.

When to use the find()

The method find() also returns an entity, but already with the data loaded, except of course relationships Lazy.

Considerations

To recover an entity, the method find() almost always is what you will need. Use the find() by default and, if you have performance issues, then check which other method can help.

To upgrade an entity, use the merge() when you already have an object populated with all new values that is write to the database.

To partial updates, use the find() or getReference() and its setter of the property you want to update.

Browser other questions tagged

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