diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Address.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Address.java new file mode 100644 index 0000000000..b20de6a471 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Address.java @@ -0,0 +1,37 @@ +package com.baeldung.jpa.uniqueconstraints; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table +public class Address implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + private String streetAddress; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getStreetAddress() { + return streetAddress; + } + + public void setStreetAddress(String streetAddress) { + this.streetAddress = streetAddress; + } +} \ No newline at end of file diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Person.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Person.java new file mode 100644 index 0000000000..c5df90df73 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Person.java @@ -0,0 +1,116 @@ +package com.baeldung.jpa.uniqueconstraints; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +@Entity +@Table(uniqueConstraints = { @UniqueConstraint(name = "UniqueNumberAndStatus", columnNames = { "personNumber", "isActive" }), + @UniqueConstraint(name = "UniqueSecurityAndDepartment", columnNames = { "securityNumber", "departmentCode" }), + @UniqueConstraint(name = "UniqueNumberAndAddress", columnNames = { "personNumber", "address" }) }) +public class Person implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + private String name; + + private String password; + + @Column(unique = true) + private String email; + + @Column(unique = true) + private Long personNumber; + + private Boolean isActive; + + private String securityNumber; + + private String departmentCode; + + @Column(unique = true) + @JoinColumn(name = "addressId", referencedColumnName = "id") + private Address address; + + 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 getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Long getPersonNumber() { + return personNumber; + } + + public void setPersonNumber(Long personNumber) { + this.personNumber = personNumber; + } + + public Boolean getIsActive() { + return isActive; + } + + public void setIsActive(Boolean isActive) { + this.isActive = isActive; + } + + public String getScode() { + return securityNumber; + } + + public void setScode(String scode) { + this.securityNumber = scode; + } + + public String getDcode() { + return departmentCode; + } + + public void setDcode(String dcode) { + this.departmentCode = dcode; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} \ No newline at end of file diff --git a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml index 666fc1500a..1166aaca71 100644 --- a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml @@ -113,6 +113,22 @@ + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.uniqueconstraints.Person + com.baeldung.jpa.uniqueconstraints.Address + true + + + + + + + + + + + org.hibernate.jpa.HibernatePersistenceProvider com.baeldung.jpa.returnmultipleentities.Channel diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueColumnIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueColumnIntegrationTest.java new file mode 100644 index 0000000000..ca776ba00b --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueColumnIntegrationTest.java @@ -0,0 +1,119 @@ +package com.baeldung.jpa.uniqueconstraints; + +import java.util.Optional; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.hibernate.exception.ConstraintViolationException; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class UniqueColumnIntegrationTest { + + private static EntityManagerFactory factory; + private static EntityManager entityManager; + + @BeforeAll + public static void setup() { + factory = Persistence.createEntityManagerFactory("jpa-unique-constraints"); + entityManager = factory.createEntityManager(); + } + + @Test + public void whenPersistPersonWithSameNumber_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setPersonNumber(2000L); + person1.setEmail("john.beth@gmail.com"); + + Person person2 = new Person(); + person2.setPersonNumber(2000L); + person2.setEmail("anthony.green@gmail.com"); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } + + @Test + public void whenPersistPersonWithSameEmail_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setPersonNumber(4000L); + person1.setEmail("timm.beth@gmail.com"); + + Person person2 = new Person(); + person2.setPersonNumber(3000L); + person2.setEmail("timm.beth@gmail.com"); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } + + @Test + public void whenPersistPersonWithSameAddress_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setPersonNumber(5000L); + person1.setEmail("chris.beck@gmail.com"); + + Address address1 = new Address(); + address1.setStreetAddress("20 Street"); + person1.setAddress(address1); + + Person person2 = new Person(); + person2.setPersonNumber(6000L); + person2.setEmail("mark.jonson@gmail.com"); + person2.setAddress(address1); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } +} \ No newline at end of file diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueConstraintIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueConstraintIntegrationTest.java new file mode 100644 index 0000000000..f12313724e --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueConstraintIntegrationTest.java @@ -0,0 +1,116 @@ +package com.baeldung.jpa.uniqueconstraints; + +import java.util.Optional; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.hibernate.exception.ConstraintViolationException; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class UniqueConstraintIntegrationTest { + private static EntityManagerFactory factory; + private static EntityManager entityManager; + + @BeforeAll + public static void setup() { + factory = Persistence.createEntityManagerFactory("jpa-unique-constraints"); + entityManager = factory.createEntityManager(); + } + + @Test + public void whenPersistPersonWithSameNumberAndStatus_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setPersonNumber(12345L); + person1.setIsActive(Boolean.TRUE); + + Person person2 = new Person(); + person2.setPersonNumber(12345L); + person2.setIsActive(Boolean.TRUE); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } + + @Test + public void whenPersistPersonWithSameSCodeAndDecode_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setDcode("Sec1"); + person1.setScode("Axybg356"); + + Person person2 = new Person(); + person2.setDcode("Sec1"); + person2.setScode("Axybg356"); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } + + @Test + public void whenPersistPersonWithSameNumberAndAddress_thenConstraintViolationException() { + Address address1 = new Address(); + address1.setStreetAddress("40 Street"); + + Person person1 = new Person(); + person1.setPersonNumber(54321L); + person1.setAddress(address1); + + Person person2 = new Person(); + person2.setPersonNumber(99999L); + person2.setAddress(address1); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } +} \ No newline at end of file