diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewBidirectionalBagTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewBidirectionalBagTest.java new file mode 100644 index 0000000000..4d7a2ab322 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewBidirectionalBagTest.java @@ -0,0 +1,120 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.jpa.test.callbacks; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.PreUpdate; + +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.hibernate.testing.TestForIssue; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@TestForIssue(jiraKey = "HHH-13466") +public class PreUpdateNewBidirectionalBagTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Person.class, Tag.class }; + } + + @Test + public void testPreUpdateModifications() { + Person person = new Person(); + person.id = 1; + + doInJPA( this::entityManagerFactory, entityManager -> { + entityManager.persist( person ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + Person p = entityManager.find( Person.class, person.id ); + assertNotNull( p ); + final Tag tag = new Tag(); + tag.id = 2; + tag.description = "description"; + tag.person = p; + final Set tags = new HashSet(); + tags.add( tag ); + p.tags = tags; + entityManager.merge( p ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + Person p = entityManager.find( Person.class, person.id ); + assertEquals( 1, p.tags.size() ); + assertEquals( "description", p.tags.iterator().next().description ); + assertNotNull( p.getLastUpdatedAt() ); + } ); + } + + @Entity(name = "Person") + @EntityListeners( PersonListener.class ) + private static class Person { + @Id + private int id; + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + private Instant lastUpdatedAt; + + public Instant getLastUpdatedAt() { + return lastUpdatedAt; + } + + public void setLastUpdatedAt(Instant lastUpdatedAt) { + this.lastUpdatedAt = lastUpdatedAt; + } + + @OneToMany(mappedBy = "person", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Collection tags = new ArrayList(); + } + + @Entity(name = "Tag") + public static class Tag { + + @Id + private int id; + + private String description; + + @ManyToOne + private Person person; + } + + public static class PersonListener { + @PreUpdate + void onPreUpdate(Object o) { + if ( Person.class.isInstance( o ) ) { + ( (Person) o ).setLastUpdatedAt( Instant.now() ); + } + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewUnidirectionalBagTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewUnidirectionalBagTest.java new file mode 100644 index 0000000000..c7febd6536 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewUnidirectionalBagTest.java @@ -0,0 +1,115 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.jpa.test.callbacks; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.PreUpdate; + +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.hibernate.testing.TestForIssue; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@TestForIssue(jiraKey = "HHH-13466") +public class PreUpdateNewUnidirectionalBagTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Person.class, Tag.class }; + } + + @Test + public void testPreUpdateModifications() { + Person person = new Person(); + person.id = 1; + + doInJPA( this::entityManagerFactory, entityManager -> { + entityManager.persist( person ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + Person p = entityManager.find( Person.class, person.id ); + assertNotNull( p ); + final Tag tag = new Tag(); + tag.id = 2; + tag.description = "description"; + final Set tags = new HashSet(); + tags.add( tag ); + p.tags = tags; + entityManager.merge( p ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + Person p = entityManager.find( Person.class, person.id ); + assertEquals( 1, p.tags.size() ); + assertEquals( "description", p.tags.iterator().next().description ); + assertNotNull( p.getLastUpdatedAt() ); + } ); + } + + @Entity(name = "Person") + @EntityListeners( PersonListener.class ) + private static class Person { + @Id + private int id; + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + private Instant lastUpdatedAt; + + public Instant getLastUpdatedAt() { + return lastUpdatedAt; + } + + public void setLastUpdatedAt(Instant lastUpdatedAt) { + this.lastUpdatedAt = lastUpdatedAt; + } + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Collection tags = new ArrayList(); + } + + @Entity(name = "Tag") + public static class Tag { + + @Id + private int id; + + private String description; + } + + public static class PersonListener { + @PreUpdate + void onPreUpdate(Object o) { + if ( Person.class.isInstance( o ) ) { + ( (Person) o ).setLastUpdatedAt( Instant.now() ); + } + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewUnidirectionalIdBagTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewUnidirectionalIdBagTest.java new file mode 100644 index 0000000000..be3325a2e6 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/callbacks/PreUpdateNewUnidirectionalIdBagTest.java @@ -0,0 +1,124 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.jpa.test.callbacks; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.PreUpdate; + +import org.hibernate.annotations.CollectionId; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.hibernate.testing.TestForIssue; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@TestForIssue(jiraKey = "HHH-13466") +public class PreUpdateNewUnidirectionalIdBagTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Person.class, Tag.class }; + } + + @Test + public void testPreUpdateModifications() { + Person person = new Person(); + person.id = 1; + + doInJPA( this::entityManagerFactory, entityManager -> { + entityManager.persist( person ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + Person p = entityManager.find( Person.class, person.id ); + assertNotNull( p ); + final Tag tag = new Tag(); + tag.id = 2; + tag.description = "description"; + final Set tags = new HashSet(); + tags.add( tag ); + p.tags = tags; + entityManager.merge( p ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + Person p = entityManager.find( Person.class, person.id ); + assertEquals( 1, p.tags.size() ); + assertEquals( "description", p.tags.iterator().next().description ); + assertNotNull( p.getLastUpdatedAt() ); + } ); + } + + @Entity(name = "Person") + @EntityListeners( PersonListener.class ) + @GenericGenerator(name="increment", strategy = "increment") + private static class Person { + @Id + private int id; + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + private Instant lastUpdatedAt; + + public Instant getLastUpdatedAt() { + return lastUpdatedAt; + } + + public void setLastUpdatedAt(Instant lastUpdatedAt) { + this.lastUpdatedAt = lastUpdatedAt; + } + + @CollectionId( + columns = @Column(name = "n_key_tag"), + type = @Type(type = "long"), + generator = "increment" ) + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Collection tags = new ArrayList(); + } + + @Entity(name = "Tag") + public static class Tag { + + @Id + private int id; + + private String description; + } + + public static class PersonListener { + @PreUpdate + void onPreUpdate(Object o) { + if ( Person.class.isInstance( o ) ) { + ( (Person) o ).setLastUpdatedAt( Instant.now() ); + } + } + } +}