JPA optimistic lock exception in Java Development

This post explains the JPA technology and its use in java development. Experts of java development India are explaining the use case of technologies- JPA and Hibernate, MySql database, Maven. Read this post and know what they want to say.

Technology: JPA stands for the Java Persistence API which is the standard from Sun Micro Systems for persistence. ORM stands for Object relational mapping. JPA is the standard for ORM. If a framework has to say ORM then it should implement all the specifications given by JPA. JPA is just specification, it needs persistence provide for CRUD operations. Hibernate, Eclipse link, etc. Are example of persistence providers.

Technologies: JPA and Hibernate, Maven, MySql database

Usecase: If you are working on Java development applications with JPA, hibernate, eclipse link you will be getting below exception often:

javax.persistence.OptimisticLockException: Row was updated or deleted by another 
transaction (or unsaved-value mapping was incorrect).

The problem is a JPA persistence provider is trying to update the Object which is not the latest version object. Generally relational databases maintain version whenever a record is updated in the table. If you want to update the record in the table you should take the latest version record from the database and update it. As we are using ORM we should take the last version object and merge it.

So in this document we can see when this error occur and how to resolve it.

1. Project Structure


Project structure will be like the above screenshot.

If you look at the project structure, it’s a maven project pom.xml is the mandatory file it. In this maven file we can configure dependencies for jpa, hibernate, java, database etc. I am using MySQL database for data storage.

Three packages, one for entity, one for Business logic, one for Application testing. If you observe there is one DTO package, if you are working on multi-tier application entities will not be directly exposed to the client layer. The entity will be converted to DTO (Data Transfer Object) which will be mapped to entities.

2. Project Dependencies


<project xmlns="" 





		<!-- JPA -->

		<!-- For connection pooling -->

		<!-- Database -->




3. JPA Configuration

As this is Hibernate added hibernate dependencies, if it is some other ORM add those dependencies.


<persistence xmlns=""

	<persistence-unit name="jpa-example" transaction-type="RESOURCE_LOCAL">
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/employee" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="root" />
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="true" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
			<property name="" value="validate" />
			<!-- Configuring Connection Pool -->
			<property name="hibernate.c3p0.min_size" value="5" />
			<property name="hibernate.c3p0.max_size" value="20" />
			<property name="hibernate.c3p0.timeout" value="500" />
			<property name="hibernate.c3p0.max_statements" value="50" />
			<property name="hibernate.c3p0.idle_test_period" value="2000" />

This is the persistence.xml, here we need to mention database credentials, the persistence name, all the required attributes by the entity manager factory.


This is the entity class which is going to persist in the database.

// Import statements

	@NamedQuery(name = EmployeeBE.FIND_ALL, query = "SELECT e FROM EmployeeBE e order by "),
@Table(name = "T_EMP")
public class EmployeeBE implements Serializable{
private static final long serialVersionUID = 1607726899931733607L;
	public static final String FIND_ALL = "naveen.examples.jpa.entity.EmployeeBE.find_all";

	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;

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

	@Column(name = "version_num")
	private int version;

//  Getters and setters


// Interface for CRUD operations.

import java.util.List;

import naveen.examples.jpa.entity.EmployeeBE;

public interface EmployeeCrud {

	List<EmployeeBE> findAllEmployeeBECol();
	EmployeeBE saveEmployee(EmployeeBE employeeBE);
	EmployeeBE updateEmployee(EmployeeBE employeeBE);
	EmployeeBE findById(int id);

// Implementatino class for CRUD operations
public class EmployeeCrudImpl implements EmployeeCrud{

	public EmployeeBE saveEmployee(EmployeeBE employeeBE) {
		EntityManager em = EntityManagerUtil.getEntityManager();
		return employeeBE;

	public EmployeeBE updateEmployee(EmployeeBE employeeBE) {
		EntityManager em = EntityManagerUtil.getEntityManager();
		return employeeBE;

	public List<EmployeeBE> findAllEmployeeBECol() {
		EntityManager em = EntityManagerUtil.getEntityManager();
		Query query = em.createNamedQuery(EmployeeBE.FIND_ALL);
		return query.getResultList();

	public EmployeeBE findById(int id) {
		EntityManager em = EntityManagerUtil.getEntityManager();
		return em.find(EmployeeBE.class, id);

// Entity Manager 
public class EntityManagerUtil {

	private static EntityManager  entityManager;

	private EntityManagerUtil() {
	public static EntityManager getEntityManager() {
			EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("jpa-example");
			return emFactory.createEntityManager();
		return entityManager;

If you look at the above code snippets we have

  1. Interface, defines business methods
  2. InterfaceImpl, implementation of business methods
  3. EntityManagerUtility, to get the entity manger object.

In the EntityManagerUtil class we are passing jpa-example parameter that we mention in persistence.xml file, so it will connect to that persistence unit.


Demonstrate how to hit the JPA optimistic lock exception.

public class Application {

	public static void main(String args[]) {
		EmployeeCrud employeeCrud = new EmployeeCrudImpl();
		List<EmployeeBE> employeeBEs = employeeCrud.findAllEmployeeBECol();
			EmployeeBE employeeBE = employeeBEs.get(0);
			// Here Optimistic lock exception
			EmployeeBE employeeBE = new EmployeeBE();
			employeeBE = employeeCrud.saveEmployee(employeeBE);

Before running the app there is no data in DB


If you run the application


If you observe there is data in the table with id 16 and version 0.

Now if you run the application in debug mode


If you observe the first update has completed, but there is same employee object in the code, as the first update method completed it’s already committed so the version becomes 1.


If you observe the screenshot the version became 1 but the object is the old one that means with version 0. Now if the second update method executed with old object, then you will get an Optimistic lock exception.


If you continue the execution, then results in an Optimistic lock exception.

6. Solution

To resolve this error we have two ways:

  1. Get the latest object from the database and set the old object values if you need those values to be persisted to the new object and merge it.
  2. For the old object set the latest version from Database.

I am following second approach, If you see screenshot I am setting the latest version number to old object


After execution in the console, no error:


This is the SQL query generated for the second update method. So the exception has not occurred.

Experts of Java development India have shared their best knowledge about JPA technology and its use in java project. If you need more details, you can ask the developers who are already applying this technology in their projects.


By using these two ways you can resolve this quite annoying error. As this is a very simple example, you can find it easily, but in real time application you will not find this much simple. So whenever you get this exception run the application in debug mode and go to the approximate code snippet where it’s showing then press F5 in debugging and go deep into the entity manager implementation of corresponding persistence provider somewhere else your entity is getting updated. Then follow eithr4 of these two techniques depending on your requirement. Keep on checking the version number in database. For each change they may or may not increase based on persistence provider implementation.


  1. OptimisticLockException JavaDoc
  2. Java Persistence/Locking

About the Author

author image
Johnny Morgan
Johnny Morgan as a technical writer at Aegis Infoways, leading Java Development India since more than 6 years. I write articles especially for Java, Python and Asp.Net. I have also got well response to write articles on CRM, Hadoop and QA


5 Comment threads
0 Thread replies
Most reacted comment
Hottest comment thread
5 Comment authors
Evan Rossh3ph3st0skoniki venkata subbaraoAngappan GanesanRamesh Babu Y Recent comment authors
newest oldest most voted
Ramesh Babu Y
Ramesh Babu Y

when we are calling the stored procedure , where actual table updates made , how to overcome this exception , can you please suggest on this

Angappan Ganesan
Angappan Ganesan

Nice explanation 🙂

koniki venkata subbarao
koniki venkata subbarao

superb explanation plz write a post on Pessimistic lock also


there is a third solution. Invoke: em.flush();em.clear();em.getTransaction().commit();
as it might for wierd reasons for example using MVVM or some async task that the context is not flushed right away and that causes problem. After that calling em.find(entity) will get you the latest version entity.

Evan Ross
Evan Ross

Poor grammar, it distracts from the actual lesson.
Also, the reference to Sun is outdated. Oracle acquired them in 2009, the article is dated 2016