JPA and Hibernate provide different methods to persist new and to update existing entities. You can choose between JPA’s persist and merge and Hibernate’s save and update methods. It seems like there are 2 pairs of 2 methods that do the same.

  1. Give More Feedback

You can use the methods persist and save to store a new entity and the methods merge and update to store the changes of a detached entity in the database. That’s why a lot of developers are wondering which of these methods they should use. Let’s take a closer look at the details and small differences of these methods. Special thanks to who provided his feedback and great insights on some of Hibernate’s hidden implementation details! Don’t want to read? You can watch it here!

Hibernate

Entity State Transitions Before we get into the details of these 4 methods, I need to give you a quick introduction to JPA’s entity lifecycle states. If an entity is attached to the current persistence context, it has the lifecycle state managed. That means that it is mapped to a database record. Your persistence provider generates the required SQL INSERT and UPDATE statements to propagate all changes. A managed entity is also stored in the 1st level cache. When you create a new entity, it’s in the transient state.

It remains in this state until you attach it to the current persistence context. I will show you how you can do that with JPA’s persist and Hibernate’s save method, in the following section. As long as an entity is in the transient state, it is not mapped to a database record and not managed by any persistence context. Entities in the detached lifecycle state are no longer managed by the persistence context. That can be the case because you closed the persistence context or you explicitly detached the entity from the current context.

Though all save, persist and saveOrUpdate in Hibernate are used for persisting object into database, there are subtle difference between them. This article explains. What is difference between save and saveOrUpdate in Hibernate are most important in any Hibernate interview.

I will get into more details about how you can reattach these entities with JPA’s merge and Hibernate’s update methods in a later part of this post. And the last lifecycle state is removed. These entities were previously in the state managed, before you scheduled them for removal. Removing entities is outside of the scope of this post, so I will not get into too many details about it. You can schedule an entity for removal by calling the remove method on the EntityManager interface. Already a member? Persisting A New Entity Using persist Or save When you create a new entity object, it’s in the transient lifecycle state.

See more on stackoverflowGive

It does not map any database record. Author a = new Author; a.setFirstName('Thorben'); a.setLastName('Janssen'); You need to attach the entity to a persistence context so that it becomes managed and gets persisted in the database. You can either use JPA’s persist or Hibernate’s save method to do that. Both methods seem to do the same, but there are a few differences. Specification vs. Proprietary API The most obvious difference is that the JPA specification defines the persist method.

You can use it with all JPA implementations. The save method, on the other hand, is Hibernate-specific.

It is, therefore, not available in other JPA implementations. But that’s only relevant if you want to be able to replace Hibernate with another JPA implementation, like Eclipse Link or OpenJPA. Return Types And Execution Of SQL Statements Another obvious difference between these 2 methods is their return type.

JPA’s persist method returns void and Hibernate’s save method returns the primary key of the entity. That might seem like a huge difference, especially when you take a closer look at Hibernate’s Javadoc and the JPA specification:. The Javadoc of Hibernate’s save method states that it generates the primary key value first: Persist the given transient instance, first assigning a generated identifier. You don’t find any information about this in the JPA specification. It doesn’t define when the primary key value has to be assigned.

Give More Feedback

So, the persistence provider can do that at any time between the call of the persist method and the flush of the persistence context. In most cases, it doesn’t make any difference if you call the save or persist method. Hibernate uses the name of the entity class and the primary key value to store the entity in the first level cache. It, therefore, needs a primary key value when it executes the persist method. In almost all situations, Hibernate immediately and triggers an SQL statement if necessary, when you call the persist or save method. But that is not the case if you use the IDENTITY strategy and try to persist an entity without an active transaction or with FlushMode.MANUAL.

If you call the persist method in one of these situations, Hibernate delays the execution of the SQL INSERT statement and creates a temporary primary key value. But if you call the save method, Hibernate performs the SQL INSERT statement immediately and retrieves the primary key value from the database. You can then retrieve it as the return value of the save method. Author a = new Author; a.setFirstName('Thorben'); a.setLastName('Janssen'); Long id = (Long) em.unwrap(Session.class).save(a); Or you can call the getter method of the primary key attribute of your managed entity if you use JPA’s persist method. Author a = new Author; a.setFirstName('Torben'); a.setLastName('Janssen'); em.persist(a); Long id = a.getId; Hibernate executes the same SQL statements when you call the persist or the save method. Which and when it does that depends on your: Not generated If you set the primary key value programmatically, e.g. to a, Hibernate only performs an SQL INSERT statement when it flushes the persistence context.

14:08:34,979 INFO TestPersistSaveMerge:237 - Save entity 14:08:35,052 INFO TestPersistSaveMerge:240 - Commit transaction 14:08:35,123 DEBUG SQL:92 - insert into Author (firstName, lastName, version, id) values (?,?,?,?). Generated with SEQUENCE strategy And if you use the SEQUENCE, Hibernate performs an SQL SELECT statement to retrieve the next value from the database sequence. Hibernate then delays the INSERT statement until it flushes the persistence context. In this example, the flush happens when the transaction gets committed. 14:10:27,994 INFO TestPersistSaveMerge:237 - Save entity 14:10:28,002 DEBUG SQL:92 - select nextval ('hibernatesequence') 14:10:28,042 INFO TestPersistSaveMerge:240 - Commit transaction 14:10:28,096 DEBUG SQL:92 - insert into Author (firstName, lastName, version, id) values (?,?,?,?) Generated with TABLE strategy You shouldn’t use the TABLE strategy because it requires row level locks on the primary key table and doesn’t scale well. If you use this strategy anyways, Hibernate performs an SQL SELECT statement to retrieve the next primary key value from the database and writes the new value to the database table.

It delays the execution of the SQL INSERT statement for the new entity until it flushes the persistence context. 14:11:17,368 INFO TestPersistSaveMerge:237 - Save entity 14:11:17,482 DEBUG SQL:92 - select tbl.nextval from hibernatesequences tbl where tbl.sequencename=? For update of tbl 14:11:17,531 DEBUG SQL:92 - insert into hibernatesequences (sequencename, nextval) values (?,?) 14:11:17,534 DEBUG SQL:92 - update hibernatesequences set nextval=? Where nextval=? And sequencename=?

14:11:17,584 INFO TestPersistSaveMerge:240 - Commit transaction 14:11:17,655 DEBUG SQL:92 - insert into Author (firstName, lastName, version, id) values (?,?,?,?) Which one to choose? You could expect that the save and persist method behave differently because there are a few differences between the JPA specification and the Javadoc of Hibernate’s proprietary methods. But almost all of these differences disappear when you take a look at the internal implementation. The only ones that remain are 2 corner cases in which Hibernate might delay the retrieval of the primary key, the return type of the method and the support by other JPA implementations. For most applications, it doesn’t make any difference if you get the generated primary key value as the return type of Hibernate’s save method or from the getter method of your primary key attribute. As long as you don’t use an extended persistence context and perform all database operations with an active transaction, I recommend using JPA’s persist method. Already a member?

Updating a managed entity JPA and Hibernate make it very easy to update a managed entity. If your entity is in the lifecycle state managed, e.g. Because you fetched it with a or the find method of the EntityManager, you just need to change the values of your entity attributes. Em = emf.createEntityManager; em.getTransaction.begin; a = em.find(Author.class, a.getId); a.setFirstName('Thorben'); log.info('Before commit'); em.getTransaction.commit; em.close; When Hibernate decides to flush the persistence context, the dirty checking mechanism will detect the change and perform the required SQL UPDATE statement. 11:41:49,178 DEBUG SQL:92 - select author0.id as id100, author0.firstName as firstNam200, author0.lastName as lastName300, author0.version as version400 from Author author0 where author0.id=?

11:41:49,191 INFO TestPersistSaveMerge:335 - Before commit 11:41:49,193 DEBUG SQL:92 - update Author set firstName=?, lastName=?, version=? And version=? You don’t need to, and you should not call Hibernate’s save method after you updated an entity. That triggers an additional SaveOrUpdate event without providing any benefits.

When Hibernate decides to flush the persistence context, it will perform the dirty check anyway to detect all changes before it executes the required SQL UPDATE statements.