From b6721961dddb72e7421dcf1b3b6c4f27a0524bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Tue, 9 May 2023 11:37:51 +0200 Subject: [PATCH] HHH-16573 Reproduce NPE with embeddable element collection with updateable = false --- ...ementCollectionWithUpdatableFalseTest.java | 133 +++++++++++++++++ ...ementCollectionWithUpdatableFalseTest.java | 135 ++++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/EmbeddableAsElementCollectionWithUpdatableFalseTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/EmbeddableAsElementCollectionWithUpdatableFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/EmbeddableAsElementCollectionWithUpdatableFalseTest.java new file mode 100644 index 0000000000..f3ed5fd3aa --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/EmbeddableAsElementCollectionWithUpdatableFalseTest.java @@ -0,0 +1,133 @@ +package org.hibernate.orm.test.embeddable; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +import static org.assertj.core.api.Assertions.assertThat; + +@DomainModel(annotatedClasses = { + EmbeddableAsElementCollectionWithUpdatableFalseTest.MyEntity.class, + EmbeddableAsElementCollectionWithUpdatableFalseTest.MyEmbeddable.class +}) +@SessionFactory +@JiraKey("HHH-16573") +public class EmbeddableAsElementCollectionWithUpdatableFalseTest { + + @AfterEach + public void tearDown(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.createMutationQuery( "delete from MyEntity" ).executeUpdate(); + } + ); + } + + @Test + public void test(SessionFactoryScope scope) { + var id = scope.fromTransaction( session -> { + var entity = new MyEntity(); + session.persist( entity ); + return entity.getId(); + } ); + + scope.inTransaction( session -> { + MyEntity entity = session.find( MyEntity.class, id ); + assertThat( entity ).isNotNull(); + assertThat( entity.getMyEmbeddables() ).isEmpty(); + entity.getMyEmbeddables().add( new MyEmbeddable( "first" ) ); + } ); + + scope.inTransaction( session -> { + MyEntity entity = session.find( MyEntity.class, id ); + assertThat( entity ).isNotNull(); + List myEmbeddables = entity.getMyEmbeddables(); + assertThat( myEmbeddables ).hasSize( 1 ); + } ); + } + + @Test + public void insertTest(SessionFactoryScope scope) { + var id = scope.fromTransaction( session -> { + var entity = new MyEntity(); + entity.getMyEmbeddables().add( new MyEmbeddable( "first" ) ); + entity.getMyEmbeddables().add( new MyEmbeddable( "third" ) ); + session.persist( entity ); + return entity.getId(); + } ); + + scope.inTransaction( session -> { + MyEntity entity = session.find( MyEntity.class, id ); + assertThat( entity ).isNotNull(); + assertThat( entity.getMyEmbeddables() ).hasSize( 2 ); + entity.getMyEmbeddables().add( 1, new MyEmbeddable( "second" ) ); + } ); + + scope.inTransaction( session -> { + MyEntity entity = session.find( MyEntity.class, id ); + assertThat( entity ).isNotNull(); + List myEmbeddables = entity.getMyEmbeddables(); + assertThat( myEmbeddables ).hasSize( 3 ); + assertThat( myEmbeddables.get( 0 ).getEmbeddedProperty() ).isEqualTo( "first" ); + assertThat( myEmbeddables.get( 1 ).getEmbeddedProperty() ).isEqualTo( "second" ); + assertThat( myEmbeddables.get( 2 ).getEmbeddedProperty() ).isEqualTo( "third" ); + } ); + } + + @Entity(name = "MyEntity") + static class MyEntity { + @Id + @GeneratedValue + private Integer id; + + @ElementCollection(fetch = FetchType.LAZY) + private List myEmbeddables = new ArrayList<>(); + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public List getMyEmbeddables() { + return myEmbeddables; + } + } + + @Embeddable + public static class MyEmbeddable { + @Column(updatable = false) + private String embeddedProperty; + + public MyEmbeddable() { + } + + public MyEmbeddable(String embeddedProperty) { + this.embeddedProperty = embeddedProperty; + } + + public String getEmbeddedProperty() { + return embeddedProperty; + } + + public void setEmbeddedProperty(String embeddedProperty) { + this.embeddedProperty = embeddedProperty; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest.java new file mode 100644 index 0000000000..5edcb7513f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/embeddable/EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest.java @@ -0,0 +1,135 @@ +package org.hibernate.orm.test.embeddable; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.OrderColumn; + +import static org.assertj.core.api.Assertions.assertThat; + +@DomainModel(annotatedClasses = { + EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest.MyEntity.class, + EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest.MyEmbeddable.class +}) +@SessionFactory +@JiraKey("HHH-16573") +public class EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest { + + @AfterEach + public void tearDown(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.createMutationQuery( "delete from MyEntity" ).executeUpdate(); + } + ); + } + + @Test + public void test(SessionFactoryScope scope) { + var id = scope.fromTransaction( session -> { + var entity = new MyEntity(); + session.persist( entity ); + return entity.getId(); + } ); + + scope.inTransaction( session -> { + MyEntity entity = session.find( MyEntity.class, id ); + assertThat( entity ).isNotNull(); + assertThat( entity.getMyEmbeddables() ).isEmpty(); + entity.getMyEmbeddables().add( new MyEmbeddable( "first" ) ); + } ); + + scope.inTransaction( session -> { + MyEntity entity = session.find( MyEntity.class, id ); + assertThat( entity ).isNotNull(); + List myEmbeddables = entity.getMyEmbeddables(); + assertThat( myEmbeddables ).hasSize( 1 ); + } ); + } + + @Test + public void insertTest(SessionFactoryScope scope) { + var id = scope.fromTransaction( session -> { + var entity = new MyEntity(); + entity.getMyEmbeddables().add( new MyEmbeddable( "first" ) ); + entity.getMyEmbeddables().add( new MyEmbeddable( "third" ) ); + session.persist( entity ); + return entity.getId(); + } ); + + scope.inTransaction( session -> { + MyEntity entity = session.find( MyEntity.class, id ); + assertThat( entity ).isNotNull(); + assertThat( entity.getMyEmbeddables() ).hasSize( 2 ); + entity.getMyEmbeddables().add( 1, new MyEmbeddable( "second" ) ); + } ); + + scope.inTransaction( session -> { + MyEntity entity = session.find( MyEntity.class, id ); + assertThat( entity ).isNotNull(); + List myEmbeddables = entity.getMyEmbeddables(); + assertThat( myEmbeddables ).hasSize( 3 ); + assertThat( myEmbeddables.get( 0 ).getEmbeddedProperty() ).isEqualTo( "first" ); + assertThat( myEmbeddables.get( 1 ).getEmbeddedProperty() ).isEqualTo( "second" ); + assertThat( myEmbeddables.get( 2 ).getEmbeddedProperty() ).isEqualTo( "third" ); + } ); + } + + @Entity(name = "MyEntity") + static class MyEntity { + @Id + @GeneratedValue + private Integer id; + + @ElementCollection(fetch = FetchType.LAZY) + @OrderColumn + private List myEmbeddables = new ArrayList<>(); + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public List getMyEmbeddables() { + return myEmbeddables; + } + } + + @Embeddable + public static class MyEmbeddable { + @Column(updatable = false) + private String embeddedProperty; + + public MyEmbeddable() { + } + + public MyEmbeddable(String embeddedProperty) { + this.embeddedProperty = embeddedProperty; + } + + public String getEmbeddedProperty() { + return embeddedProperty; + } + + public void setEmbeddedProperty(String embeddedProperty) { + this.embeddedProperty = embeddedProperty; + } + } +}