diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/CreditCardPayment.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/CreditCardPayment.java new file mode 100644 index 0000000000..6eb41f7ccc --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/CreditCardPayment.java @@ -0,0 +1,20 @@ +package com.baeldung.jpa.hibernateunproxy; + +import javax.persistence.Entity; +import java.math.BigDecimal; + +@Entity +public class CreditCardPayment extends Payment { + + private String cardNumber; + + CreditCardPayment(BigDecimal amount, WebUser webUser, String cardNumber) { + this.amount = amount; + this.webUser = webUser; + this.cardNumber = cardNumber; + } + + protected CreditCardPayment() { + } + +} diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/Payment.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/Payment.java new file mode 100644 index 0000000000..9e70da5f65 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/Payment.java @@ -0,0 +1,47 @@ +package com.baeldung.jpa.hibernateunproxy; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.ManyToOne; +import java.math.BigDecimal; +import java.util.Objects; + +@Entity +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +public abstract class Payment { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + protected WebUser webUser; + + protected BigDecimal amount; + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + Payment payment = (Payment) o; + + return Objects.equals(id, payment.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + protected Payment() { + } + +} diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/PaymentReceipt.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/PaymentReceipt.java new file mode 100644 index 0000000000..530839eef4 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/PaymentReceipt.java @@ -0,0 +1,53 @@ +package com.baeldung.jpa.hibernateunproxy; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import java.util.Objects; +import java.util.UUID; + +@Entity +public class PaymentReceipt { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @OneToOne(fetch = FetchType.LAZY) + private Payment payment; + + private String transactionNumber; + + PaymentReceipt(Payment payment) { + this.payment = payment; + this.transactionNumber = UUID.randomUUID().toString(); + } + + public Payment getPayment() { + return payment; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + PaymentReceipt that = (PaymentReceipt) o; + + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + protected PaymentReceipt() { + } + +} diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/WebUser.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/WebUser.java new file mode 100644 index 0000000000..d3f82bacd4 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/WebUser.java @@ -0,0 +1,42 @@ +package com.baeldung.jpa.hibernateunproxy; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Objects; + +@Entity +public class WebUser { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + WebUser(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + WebUser webUser = (WebUser) o; + + return Objects.equals(id, webUser.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + protected WebUser() { + } + +} 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 f428fea07b..19ecae8491 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 @@ -77,4 +77,24 @@ + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.hibernateunproxy.Payment + com.baeldung.jpa.hibernateunproxy.CreditCardPayment + com.baeldung.jpa.hibernateunproxy.PaymentReceipt + com.baeldung.jpa.hibernateunproxy.WebUser + true + + + + + + + + + + + + + diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/hibernateunproxy/HibernateProxyIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/hibernateunproxy/HibernateProxyIntegrationTest.java new file mode 100644 index 0000000000..a831639f5d --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/hibernateunproxy/HibernateProxyIntegrationTest.java @@ -0,0 +1,75 @@ +package com.baeldung.jpa.hibernateunproxy; + +import org.hibernate.Hibernate; +import org.hibernate.proxy.HibernateProxy; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import java.math.BigDecimal; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class HibernateProxyIntegrationTest { + + private static EntityManager entityManager; + + @BeforeAll + public static void setup() { + EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-h2-hibernate-unproxy"); + entityManager = factory.createEntityManager(); + populateH2DB(); + } + + @Test + public void givenPaymentReceipt_whenAccessingPayment_thenVerifyType() { + PaymentReceipt paymentReceipt = entityManager.find(PaymentReceipt.class, 3L); + Assert.assertEquals(true, paymentReceipt.getPayment() instanceof HibernateProxy); + } + + @Test + public void givenWebUserProxy_whenCreatingPayment_thenExecuteSingleStatement() { + entityManager.getTransaction().begin(); + + WebUser webUser = entityManager.getReference(WebUser.class, 1L); + Payment payment = new CreditCardPayment(new BigDecimal(100), webUser, "CN-1234"); + entityManager.persist(payment); + + entityManager.getTransaction().commit(); + Assert.assertEquals(true, webUser instanceof HibernateProxy); + } + + @Test + public void givenPaymentReceipt_whenCastingPaymentToConcreteClass_thenThrowClassCastException() { + PaymentReceipt paymentReceipt = entityManager.find(PaymentReceipt.class, 3L); + assertThrows(ClassCastException.class, () -> { + CreditCardPayment creditCardPayment = (CreditCardPayment) paymentReceipt.getPayment(); + }); + } + + @Test + public void givenPaymentReceipt_whenPaymentIsUnproxied_thenReturnRealEntityObject() { + PaymentReceipt paymentReceipt = entityManager.find(PaymentReceipt.class, 3L); + Assert.assertEquals(true, Hibernate.unproxy(paymentReceipt.getPayment()) instanceof CreditCardPayment); + } + + private static void populateH2DB() { + entityManager.getTransaction().begin(); + + WebUser webUser = new WebUser("name"); + entityManager.persist(webUser); + + Payment payment = new CreditCardPayment(new BigDecimal(100), webUser, "CN-1234"); + entityManager.persist(payment); + + PaymentReceipt receipt = new PaymentReceipt(payment); + entityManager.persist(receipt); + + entityManager.getTransaction().commit(); + entityManager.clear(); + } + +}