diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml index 3e33aca5ae..6f11888643 100644 --- a/persistence-modules/hibernate-annotations/pom.xml +++ b/persistence-modules/hibernate-annotations/pom.xml @@ -28,7 +28,7 @@ ${org.springframework.data.version} - org.hibernate + org.hibernate.orm hibernate-core ${hibernate-core.version} @@ -48,12 +48,12 @@ ${commons-lang3.version} - org.hibernate + org.hibernate.orm hibernate-testing ${hibernate-core.version} - org.hibernate + org.hibernate.orm hibernate-spatial ${hibernate-core.version} @@ -87,7 +87,7 @@ 6.0.6 3.0.3 - 6.1.7.Final + 6.4.2.Final true 9.0.0.M26 3.3.1 diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java index 8f1794b979..1103aa8523 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java @@ -1,7 +1,12 @@ package com.baeldung.hibernate.customtypes; +import org.hibernate.dialect.Dialect; +import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation; +import org.hibernate.type.BasicType; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; +import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; +import org.hibernate.type.spi.TypeConfiguration; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -48,4 +53,9 @@ public class LocalDateStringJavaDescriptor extends AbstractArrayTypeDescriptor resolveType(TypeConfiguration typeConfiguration, Dialect dialect, BasicType basicType, ColumnTypeInformation columnTypeInformation, JdbcTypeIndicators jdbcTypeIndicators) { + return null; + } } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/softdelete/model/SoftDeletePerson.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/softdelete/model/SoftDeletePerson.java new file mode 100644 index 0000000000..730dfb9590 --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/softdelete/model/SoftDeletePerson.java @@ -0,0 +1,59 @@ +package com.baeldung.hibernate.softdelete.model; + +import java.util.List; + +import org.hibernate.annotations.SoftDelete; +import org.hibernate.annotations.SoftDeleteType; +import org.hibernate.type.YesNoConverter; + +import jakarta.persistence.CollectionTable; +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.NamedNativeQueries; +import jakarta.persistence.NamedNativeQuery; + +@Entity +@NamedNativeQueries({ + @NamedNativeQuery(name = "getDeletedPerson", query = "SELECT id, name FROM SoftDeletePerson sdp where sdp.deleted = true", resultClass = SoftDeletePerson.class) }) +@SoftDelete +public class SoftDeletePerson { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private Long id; + + private String name; + + @ElementCollection(fetch = FetchType.EAGER) + @CollectionTable(name = "Emails", joinColumns = @JoinColumn(name = "id")) + @Column(name = "emailId") + @SoftDelete(strategy = SoftDeleteType.ACTIVE, converter = YesNoConverter.class) + private List emailIds; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getEmailIds() { + return emailIds; + } + + public void setEmailIds(List emailIds) { + this.emailIds = emailIds; + } + + @Override + public String toString() { + return "SoftDeletePerson{" + "id=" + id + ", name='" + name + '\'' + ", emailIds=" + emailIds + '}'; + } +} diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/softdelete/SoftDeletePersonIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/softdelete/SoftDeletePersonIntegrationTest.java new file mode 100644 index 0000000000..68d989ba51 --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/softdelete/SoftDeletePersonIntegrationTest.java @@ -0,0 +1,110 @@ +package com.baeldung.hibernate.softdelete; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.ArrayList; +import java.util.List; + +import org.h2.Driver; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.service.ServiceRegistry; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.baeldung.hibernate.softdelete.model.SoftDeletePerson; + +public class SoftDeletePersonIntegrationTest { + + private static SessionFactory sessionFactory; + + private static Session session; + + SoftDeletePerson person1 = new SoftDeletePerson(); + SoftDeletePerson person2 = new SoftDeletePerson(); + + @BeforeAll + public static void beforeTests() { + Configuration configuration = new Configuration().addAnnotatedClass(SoftDeletePerson.class) + .setProperty("hibernate.dialect", H2Dialect.class.getName()) + .setProperty("hibernate.connection.driver_class", Driver.class.getName()) + .setProperty("hibernate.connection.url", "jdbc:h2:mem:test") + .setProperty("hibernate.connection.username", "sa") + .setProperty("hibernate.connection.password", "") + .setProperty("hibernate.hbm2ddl.auto", "update") + .setProperty("hibernate.show_sql", "true"); + + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()) + .build(); + + sessionFactory = configuration.buildSessionFactory(serviceRegistry); + } + + @BeforeEach + public void setup() { + session = sessionFactory.openSession(); + session.beginTransaction(); + SoftDeletePerson person1 = new SoftDeletePerson(); + person1.setName("Person1"); + List emailIds = new ArrayList<>(); + emailIds.add("id1@dummy.com"); + emailIds.add("id2@dummy.com"); + person1.setEmailIds(emailIds); + SoftDeletePerson person2 = new SoftDeletePerson(); + person2.setName("Person2"); + List emailIdsPerson2 = new ArrayList<>(); + emailIdsPerson2.add("person2Id1@dummy.com"); + emailIdsPerson2.add("person2Id2@dummy.com"); + person2.setEmailIds(emailIdsPerson2); + session.save(person1); + session.save(person2); + session.getTransaction() + .commit(); + + assertNotNull(person1.getName()); + assertNotNull(person2.getName()); + System.out.println(person1); + System.out.println(person2); + } + + @Test + void whenDeletingUsingSoftDelete_ThenEntityAndCollectionAreDeleted() { + session.beginTransaction(); + person1 = session.createQuery("from SoftDeletePerson where name='Person1'", SoftDeletePerson.class) + .getSingleResult(); + person2 = session.createQuery("from SoftDeletePerson where name='Person2'", SoftDeletePerson.class) + .getSingleResult(); + + assertNotNull(person1); + assertNotNull(person2); + + session.delete(person2); + List emailIds = person1.getEmailIds(); + emailIds.remove(0); + person1.setEmailIds(emailIds); + session.save(person1); + session.getTransaction() + .commit(); + List activeRows = session.createQuery("from SoftDeletePerson") + .list(); + List deletedRows = session.createNamedQuery("getDeletedPerson", SoftDeletePerson.class) + .getResultList(); + session.close(); + + assertNotNull(person1.getName()); + System.out.println("-------------Active Rows-----------"); + activeRows.forEach(row -> System.out.println(row)); + System.out.println("-------------Deleted Rows-----------"); + deletedRows.forEach(row -> System.out.println(row)); + } + + @AfterAll + static void afterTests() { + sessionFactory.close(); + } +}