Difference between save() and persist() in Hibernate

In this post, we will see difference between save() and persist() method in Hibernate with example.

First, we will see the difference between the save() and persist() methods in tabular form. Later we will see all points in detail. Also, we will see complete example Hibernate Session save() and persist() methods.

Note – Both save() and persist() method is defined in Session interface fires INSERT query.

save()persist()
The return type of save() method is Serializable, returns generated id. The return type of persit() method is void.
The save() method is only supported by Hibernate i.e hibernate specific. The persist() method is supported by Hibernate as well as JPA EntityManager (In EntityManager persist() method has been defined).
If the id generation type is AUTO, using the save() method we can pass identifiers in the entity. If the id generation type is AUTO and we pass identifier in persist() method, it will throw detached entity passed to persist exception.

Let’s see all points in details.

The return type of save() method is Serializable where as return type of persist() method is void.

The save() method is defined in Session interface as below.

Serializable save(Object object);

Another overloaded version of save() method.

Serializable save(String entityName, Object object);

Check docs for save() method here.

The persist() method is defined as below.

void persist(Object object);

Check docs for Session’s persist() method here.

The save() method is hibernate specific where as persist() method is defined in JPA EntityMnager and Hibernate.

If you look into JPA EntityManger(see here) there is no method save() method has been defined where we can find persist() method in JPA EntityManager. The persist() method is defined as below in JPA EntityManager.

public void persist(Object entity);

If the id generation type is AUTO, In save() method we can pass identifier, where as if we pass identifier in persist() method it will throw exception.

Consider we have entity Student.java as below.

package com.javatute.entity;


@Entity
public class Student implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Column(name = "name")
	private String name;

	@Column(name = "roll_number")
	private String rollNumber;

	@Column(name = "university")
	private String university;

}
package com.javatute.serviceimpl;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Session;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.javatute.entity.Student;
import com.javatute.service.StudentService;

@Service
public class StudentServiceImpl implements StudentService {

	@PersistenceContext
	private EntityManager entityManager;

	@Transactional
	public Student save(Student student) {
		Session session = entityManager.unwrap(Session.class);
		session.save(student);
		return student;
	}

	@Transactional
	public Student persist(Student student) {
		Session session = entityManager.unwrap(Session.class);
		session.persist(student);

		// we can also do --but same doesn't apply for save() method
		// entityManager.persist(student);

		session.persist(student);
		return student;
	}

	@Transactional
	public Student retrieveEntity(Long id) {

		Session session = entityManager.unwrap(Session.class);
		Student student = session.load(Student.class, id);
		System.out.println("name is" + student.getName());
		return student;
	}

}

While using the save() method we can pass id in request data no exception will throw. But since we have mentioned @GeneratedValue(strategy = GenerationType.AUTO) with id field in the entity, id will generate by hibernate. The id value that we pass in request data will not come into effect.

Difference between save() and persist() in Hibernate

But in case of persist() method it will throw below exception org.hibernate.PersistentObjectException: detached entity passed to persist: com.javatute.entity.Student.

Difference between save() and persist() in Hibernate

Let’s see complete example using spring boo that demonstarte difference between save() and persist() in Hibernate.

Create maven project, Don’t forget to check ‘Create a simple project (skip)’ click on next.  Fill all details(GroupId – hibernategetvsload, ArtifactId – hibernategetvsload, and name – hibernategetvsload) and click on finish. Keep packaging as the jar.

Add maven dependency.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>hibernategetvsload</groupId>
	<artifactId>hibernategetvsload</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>hibernategetvsload</name>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.2.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
	</dependencies>
</project>

The directory structure of the application.

Difference between save() and persist() in Hibernate

Student.java

package com.javatute.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Student implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Column(name = "name")
	private String name;

	@Column(name = "roll_number")
	private String rollNumber;

	@Column(name = "university")
	private String university;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getRollNumber() {
		return rollNumber;
	}

	public void setRollNumber(String rollNumber) {
		this.rollNumber = rollNumber;
	}

	public String getUniversity() {
		return university;
	}

	public void setUniversity(String university) {
		this.university = university;
	}

}

StudentService.java

package com.javatute.service;

import org.springframework.stereotype.Component;

import com.javatute.entity.Student;

@Component
public interface StudentService {

	public Student save(Student student);
	
	public Student persist(Student student);

	public Student retrieveEntity(Long id);
}

StudentServiceImpl.java

package com.javatute.serviceimpl;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Session;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.javatute.entity.Student;
import com.javatute.service.StudentService;

@Service
public class StudentServiceImpl implements StudentService {

	@PersistenceContext
	private EntityManager entityManager;

	@Transactional
	public Student save(Student student) {
		Session session = entityManager.unwrap(Session.class);
		session.save(student);
		return student;
	}

	@Transactional
	public Student persist(Student student) {
		Session session = entityManager.unwrap(Session.class);
		session.persist(student);

		// we can also do --but same doesn't apply for save() method
		// entityManager.persist(student);

		session.persist(student);
		return student;
	}

	@Transactional
	public Student retrieveEntity(Long id) {

		Session session = entityManager.unwrap(Session.class);
		Student student = session.load(Student.class, id);
		System.out.println("name is" + student.getName());
		return student;
	}

}

StudentController.java

package com.javatute.serviceimpl;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Session;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.javatute.entity.Student;
import com.javatute.service.StudentService;

@Service
public class StudentServiceImpl implements StudentService {

	@PersistenceContext
	private EntityManager entityManager;

	@Transactional
	public Student save(Student student) {
		Session session = entityManager.unwrap(Session.class);
		session.save(student);
		return student;
	}

	@Transactional
	public Student persist(Student student) {
		Session session = entityManager.unwrap(Session.class);
		session.persist(student);

		// we can also do --but same doesn't apply for save() method
		// entityManager.persist(student);

		session.persist(student);
		return student;
	}

	@Transactional
	public Student retrieveEntity(Long id) {

		Session session = entityManager.unwrap(Session.class);
		Student student = session.load(Student.class, id);
		System.out.println("name is" + student.getName());
		return student;
	}

}

SpringMain.java

package com.javatute.main;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = "com.javatute.*")
@EntityScan("com.javatute.*")
public class SpringMain {
	public static void main(String[] args) {
		SpringApplication.run(SpringMain.class, args);
	}
}

application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/springbootcrudexample
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
server.port = 9091
#logging.level.org.hibernate.type.descriptor.sql=trace

See more differences in Hibernate.

You may like.

Spring Data JPA.

That’s all about difference between save() and persist() method in Hibernate.

See docs here.

Download the source code from github.