BAEL-1730: Optimistic Locking in JPA
Tests for the article.
This commit is contained in:
parent
7afbfb6968
commit
fc14d426c5
|
@ -1,5 +1,7 @@
|
|||
package com.baeldung.hibernate;
|
||||
|
||||
import com.baeldung.hibernate.optimisticlocking.OptimisticLockingCourse;
|
||||
import com.baeldung.hibernate.optimisticlocking.OptimisticLockingStudent;
|
||||
import com.baeldung.hibernate.pessimisticlocking.Individual;
|
||||
import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingCourse;
|
||||
import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingEmployee;
|
||||
|
@ -70,6 +72,8 @@ public class HibernateUtil {
|
|||
metadataSources.addAnnotatedClass(PessimisticLockingCourse.class);
|
||||
metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Customer.class);
|
||||
metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Address.class);
|
||||
metadataSources.addAnnotatedClass(OptimisticLockingCourse.class);
|
||||
metadataSources.addAnnotatedClass(OptimisticLockingStudent.class);
|
||||
|
||||
Metadata metadata = metadataSources.buildMetadata();
|
||||
return metadata.getSessionFactoryBuilder()
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.hibernate.optimisticlocking;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class OptimisticLockingCourse {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@ManyToOne
|
||||
@JoinTable(name = "optimistic_student_course")
|
||||
private OptimisticLockingStudent student;
|
||||
|
||||
public OptimisticLockingCourse(Long id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public OptimisticLockingCourse() {
|
||||
}
|
||||
|
||||
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 OptimisticLockingStudent getStudent() {
|
||||
return student;
|
||||
}
|
||||
|
||||
public void setStudent(OptimisticLockingStudent student) {
|
||||
this.student = student;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.hibernate.optimisticlocking;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
public class OptimisticLockingStudent {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String lastName;
|
||||
@Version
|
||||
private Integer version;
|
||||
|
||||
@OneToMany(mappedBy = "student")
|
||||
private List<OptimisticLockingCourse> courses;
|
||||
|
||||
public OptimisticLockingStudent(Long id, String name, String lastName, List<OptimisticLockingCourse> courses) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.lastName = lastName;
|
||||
this.courses = courses;
|
||||
}
|
||||
|
||||
public OptimisticLockingStudent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public List<OptimisticLockingCourse> getCourses() {
|
||||
return courses;
|
||||
}
|
||||
|
||||
public void setCourses(List<OptimisticLockingCourse> courses) {
|
||||
this.courses = courses;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package com.baeldung.hibernate.optimisticlocking;
|
||||
|
||||
import com.baeldung.hibernate.HibernateUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class OptimisticLockingIntegrationTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
EntityManager entityManager = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingCourse course = new OptimisticLockingCourse(1L, "MATH");
|
||||
OptimisticLockingStudent student = new OptimisticLockingStudent(1L, "John", "Doe", Arrays.asList(course));
|
||||
course.setStudent(student);
|
||||
entityManager.persist(course);
|
||||
entityManager.persist(student);
|
||||
entityManager.getTransaction()
|
||||
.commit();
|
||||
entityManager.close();
|
||||
}
|
||||
|
||||
@After
|
||||
public void clean() throws IOException {
|
||||
EntityManager entityManager = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingCourse course = entityManager.find(OptimisticLockingCourse.class, 1L);
|
||||
OptimisticLockingStudent student = entityManager.find(OptimisticLockingStudent.class, 1L);
|
||||
entityManager.remove(course);
|
||||
entityManager.remove(student);
|
||||
entityManager.getTransaction()
|
||||
.commit();
|
||||
entityManager.close();
|
||||
}
|
||||
|
||||
@Test(expected = OptimisticLockException.class)
|
||||
public void givenVersionedEntities_whenConcurrentUpdate_thenOptimisticLockException() throws IOException {
|
||||
EntityManager em = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L);
|
||||
|
||||
EntityManager em2 = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L);
|
||||
student2.setName("RICHARD");
|
||||
em2.persist(student2);
|
||||
em2.getTransaction()
|
||||
.commit();
|
||||
em2.close();
|
||||
|
||||
student.setName("JOHN");
|
||||
em.persist(student);
|
||||
em.getTransaction()
|
||||
.commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test(expected = OptimisticLockException.class)
|
||||
public void givenVersionedEntitiesWithLockByFindMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException {
|
||||
EntityManager em = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L, LockModeType.OPTIMISTIC);
|
||||
|
||||
EntityManager em2 = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
|
||||
student2.setName("RICHARD");
|
||||
em2.persist(student2);
|
||||
em2.getTransaction()
|
||||
.commit();
|
||||
em2.close();
|
||||
|
||||
student.setName("JOHN");
|
||||
em.persist(student);
|
||||
em.getTransaction()
|
||||
.commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test(expected = OptimisticLockException.class)
|
||||
public void givenVersionedEntitiesWithLockByRefreshMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException {
|
||||
EntityManager em = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L);
|
||||
em.refresh(student, LockModeType.OPTIMISTIC);
|
||||
|
||||
EntityManager em2 = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L);
|
||||
em.refresh(student, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
|
||||
student2.setName("RICHARD");
|
||||
em2.persist(student2);
|
||||
em2.getTransaction()
|
||||
.commit();
|
||||
em2.close();
|
||||
|
||||
student.setName("JOHN");
|
||||
em.persist(student);
|
||||
em.getTransaction()
|
||||
.commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test(expected = OptimisticLockException.class)
|
||||
public void givenVersionedEntitiesWithLockByLockMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException {
|
||||
EntityManager em = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L);
|
||||
em.lock(student, LockModeType.OPTIMISTIC);
|
||||
|
||||
EntityManager em2 = getEntityManagerWithOpenTransaction();
|
||||
OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L);
|
||||
em.lock(student, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
|
||||
student2.setName("RICHARD");
|
||||
em2.persist(student2);
|
||||
em2.getTransaction()
|
||||
.commit();
|
||||
em2.close();
|
||||
|
||||
student.setName("JOHN");
|
||||
em.persist(student);
|
||||
em.getTransaction()
|
||||
.commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
protected static EntityManager getEntityManagerWithOpenTransaction() throws IOException {
|
||||
String propertyFileName = "hibernate-pessimistic-locking.properties";
|
||||
EntityManager entityManager = HibernateUtil.getSessionFactory(propertyFileName)
|
||||
.openSession();
|
||||
entityManager.getTransaction()
|
||||
.begin();
|
||||
|
||||
return entityManager;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue