From 4783ef11f068563be626e3e24190982e80b089bf Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Sun, 16 May 2021 09:33:56 +0200 Subject: [PATCH] HHH-14608 Add test for issue (cherry picked from commit 8dcf6f983b18d1f5d6a6cc3d66b0f7cb84d2d935) --- .../jpa/test/ops/MergeJpaComplianceTest.java | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/jpa/test/ops/MergeJpaComplianceTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/ops/MergeJpaComplianceTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/ops/MergeJpaComplianceTest.java new file mode 100644 index 0000000000..1da7fd5534 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/ops/MergeJpaComplianceTest.java @@ -0,0 +1,211 @@ +package org.hibernate.jpa.test.ops; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.persistence.CascadeType; +import javax.persistence.Embeddable; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.hibernate.testing.TestForIssue; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil2.fromTransaction; +import static org.hibernate.testing.transaction.TransactionUtil2.inTransaction; + +@TestForIssue( jiraKey = "HHH-14608") +public class MergeJpaComplianceTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + Person.class, Occupation.class, PersonOccupation.class + }; + } + + @Override + protected void addConfigOptions(Map config) { + config.put( org.hibernate.cfg.AvailableSettings.JPA_PROXY_COMPLIANCE, true ); + } + + @Test + public void testMerge() { + Person person = fromTransaction( + entityManagerFactory(), + entityManager -> { + Person p; + p = new Person( "1", "Fab" ); + Occupation t = new Occupation( 1l, "Some work" ); + + entityManager.persist( p ); + entityManager.persist( t ); + + entityManager.flush(); + + PersonOccupation participant = new PersonOccupation( p, t ); + entityManager.persist( participant ); + return p; + } + ); + + inTransaction( + entityManagerFactory(), + entityManager -> { + person.setName( "Fabiana" ); + entityManager.merge( person ); + } + ); + } + + @Entity(name = "Person") + public static class Person { + @Id + private String id; + + private String name; + + @OneToMany(mappedBy = "pk.person", cascade = CascadeType.ALL, orphanRemoval = true) + private List occupations; + + public Person() { + + } + + public Person(String id, String name) { + this.id = id; + this.name = name; + } + + protected void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public List getOccupations() { + return occupations; + } + + protected void addOccupationPeoplet(PersonOccupation personOccupation) { + if ( this.occupations == null ) { + occupations = new ArrayList<>(); + } + this.occupations.add( personOccupation ); + personOccupation.getPk().setPerson( this ); + } + + protected void setOccupations(List occupations) { + this.occupations = occupations; + } + } + + @Entity(name = "Occupation") + public static class Occupation { + @Id + private long id; + + private String name; + + @OneToMany(mappedBy = "pk.occupation", cascade = CascadeType.ALL) + private List personOccupations; + + protected Occupation() { + } + + public Occupation(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + protected void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + protected void setName(String name) { + this.name = name; + } + + public List getPersonOccupations() { + return personOccupations; + } + + protected void addPersonOccupation(PersonOccupation participant) { + if ( personOccupations == null ) { + personOccupations = new ArrayList<>(); + } + personOccupations.add( participant ); + participant.getPk().setOccupation( this ); + } + + protected void setPersonOccupations(List personOccupations) { + this.personOccupations = personOccupations; + } + } + + @Entity(name = "PersonOccupation") + public static class PersonOccupation { + @EmbeddedId + private PersonOccupationPK pk = new PersonOccupationPK(); + + protected PersonOccupation() { + } + + public PersonOccupation(Person person, Occupation occupation) { + person.addOccupationPeoplet( this ); + occupation.addPersonOccupation( this ); + } + + public PersonOccupationPK getPk() { + return pk; + } + + public void setPk(PersonOccupationPK pk) { + this.pk = pk; + } + } + + @Embeddable + public static class PersonOccupationPK implements Serializable { + + @ManyToOne(fetch = FetchType.LAZY) + private Person person; + + @ManyToOne(fetch = FetchType.LAZY) + private Occupation occupation; + + public Person getPerson() { + return person; + } + + public void setPerson(Person person) { + this.person = person; + } + + public Occupation getOccupation() { + return occupation; + } + + public void setOccupation(Occupation occupation) { + this.occupation = occupation; + } + } + +}