diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/LineItem.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/LineItem.java new file mode 100644 index 0000000000..9ab2dd4e74 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/LineItem.java @@ -0,0 +1,45 @@ +package com.baeldung.jpa.removal; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import java.util.Objects; + +@Entity +public class LineItem { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + @ManyToOne + private OrderRequest orderRequest; + + public LineItem(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + LineItem lineItem = (LineItem) o; + + return Objects.equals(id, lineItem.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + protected LineItem() { + } +} diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/OrderRequest.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/OrderRequest.java new file mode 100644 index 0000000000..739c110d8c --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/OrderRequest.java @@ -0,0 +1,43 @@ +package com.baeldung.jpa.removal; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import java.util.List; + +@Entity +public class OrderRequest { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) + private ShipmentInfo shipmentInfo; + + @OneToMany(orphanRemoval = true, cascade = CascadeType.PERSIST, mappedBy = "orderRequest") + private List lineItems; + + public OrderRequest(ShipmentInfo shipmentInfo) { + this.shipmentInfo = shipmentInfo; + } + + public OrderRequest(List lineItems) { + this.lineItems = lineItems; + } + + public void removeLineItem(LineItem lineItem) { + lineItems.remove(lineItem); + } + + public void setLineItems(List lineItems) { + this.lineItems = lineItems; + } + + protected OrderRequest() { + } +} diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/ShipmentInfo.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/ShipmentInfo.java new file mode 100644 index 0000000000..12274bcadf --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/removal/ShipmentInfo.java @@ -0,0 +1,23 @@ +package com.baeldung.jpa.removal; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class ShipmentInfo { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + public ShipmentInfo(String name) { + this.name = name; + } + + protected ShipmentInfo() { + } +} 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 28a929f912..88378bd8db 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 @@ -1,25 +1,43 @@ - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.equality.EqualByJavaDefault - com.baeldung.jpa.equality.EqualById - com.baeldung.jpa.equality.EqualByBusinessKey - true - - - - - - - - - - - - + version="2.2"> + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.equality.EqualByJavaDefault + com.baeldung.jpa.equality.EqualById + com.baeldung.jpa.equality.EqualByBusinessKey + true + + + + + + + + + + + + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.removal.ShipmentInfo + com.baeldung.jpa.removal.LineItem + com.baeldung.jpa.removal.OrderRequest + true + + + + + + + + + + + + diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/removal/CascadeTypeRemoveIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/removal/CascadeTypeRemoveIntegrationTest.java new file mode 100644 index 0000000000..8f99723ac6 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/removal/CascadeTypeRemoveIntegrationTest.java @@ -0,0 +1,73 @@ +package com.baeldung.jpa.removal; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.List; + +public class CascadeTypeRemoveIntegrationTest { + + private static EntityManagerFactory factory; + private static EntityManager entityManager; + + @BeforeClass + public static void setup() { + factory = Persistence.createEntityManagerFactory("jpa-h2-removal"); + entityManager = factory.createEntityManager(); + } + + @Test + public void whenOrderRequestIsDeleted_thenDeleteShipmentInfo() { + createOrderRequestWithShipmentInfo(); + + OrderRequest orderRequest = entityManager.find(OrderRequest.class, 1L); + + entityManager.getTransaction().begin(); + entityManager.remove(orderRequest); + entityManager.getTransaction().commit(); + + Assert.assertEquals(0, findAllOrderRequest().size()); + Assert.assertEquals(0, findAllShipmentInfo().size()); + } + + private void createOrderRequestWithShipmentInfo() { + ShipmentInfo shipmentInfo = new ShipmentInfo("name"); + OrderRequest orderRequest = new OrderRequest(shipmentInfo); + + entityManager.getTransaction().begin(); + entityManager.persist(orderRequest); + entityManager.getTransaction().commit(); + + Assert.assertEquals(1, findAllOrderRequest().size()); + Assert.assertEquals(1, findAllShipmentInfo().size()); + } + + private List findAllOrderRequest() { + CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(OrderRequest.class); + Root root = cq.from(OrderRequest.class); + CriteriaQuery findAll = cq.select(root); + TypedQuery findAllQuery = entityManager.createQuery(findAll); + + return findAllQuery.getResultList(); + } + + private List findAllShipmentInfo() { + CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(ShipmentInfo.class); + Root root = cq.from(ShipmentInfo.class); + CriteriaQuery findAll = cq.select(root); + TypedQuery findAllQuery = entityManager.createQuery(findAll); + + return findAllQuery.getResultList(); + } + +} diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/removal/OrphanRemovalIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/removal/OrphanRemovalIntegrationTest.java new file mode 100644 index 0000000000..615e8cf3a8 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/removal/OrphanRemovalIntegrationTest.java @@ -0,0 +1,92 @@ +package com.baeldung.jpa.removal; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.PersistenceException; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.ArrayList; +import java.util.List; + +public class OrphanRemovalIntegrationTest { + + private static EntityManagerFactory factory; + private static EntityManager entityManager; + + @Before + public void setup() { + factory = Persistence.createEntityManagerFactory("jpa-h2-removal"); + entityManager = factory.createEntityManager(); + } + + @Test + public void whenLineItemIsRemovedFromOrderRequest_thenDeleteOrphanedLineItem() { + createOrderRequestWithLineItems(); + + OrderRequest orderRequest = entityManager.find(OrderRequest.class, 1L); + LineItem lineItem = entityManager.find(LineItem.class, 2L); + orderRequest.removeLineItem(lineItem); + + entityManager.getTransaction().begin(); + entityManager.merge(orderRequest); + entityManager.getTransaction().commit(); + + Assert.assertEquals(1, findAllOrderRequest().size()); + Assert.assertEquals(2, findAllLineItem().size()); + } + + @Test(expected = PersistenceException.class) + public void whenLineItemsIsReassigned_thenThrowAnException() { + createOrderRequestWithLineItems(); + + OrderRequest orderRequest = entityManager.find(OrderRequest.class, 1L); + orderRequest.setLineItems(new ArrayList<>()); + + entityManager.getTransaction().begin(); + entityManager.merge(orderRequest); + entityManager.getTransaction().commit(); + } + + private void createOrderRequestWithLineItems() { + List lineItems = new ArrayList<>(); + lineItems.add(new LineItem("line item 1")); + lineItems.add(new LineItem("line item 2")); + lineItems.add(new LineItem("line item 3")); + + OrderRequest orderRequest = new OrderRequest(lineItems); + + entityManager.getTransaction().begin(); + entityManager.persist(orderRequest); + entityManager.getTransaction().commit(); + + Assert.assertEquals(1, findAllOrderRequest().size()); + Assert.assertEquals(3, findAllLineItem().size()); + } + + private List findAllOrderRequest() { + CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(OrderRequest.class); + Root root = cq.from(OrderRequest.class); + CriteriaQuery findAll = cq.select(root); + TypedQuery findAllQuery = entityManager.createQuery(findAll); + + return findAllQuery.getResultList(); + } + + private List findAllLineItem() { + CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(LineItem.class); + Root root = cq.from(LineItem.class); + CriteriaQuery findAll = cq.select(root); + TypedQuery findAllQuery = entityManager.createQuery(findAll); + + return findAllQuery.getResultList(); + } +}