From 9969f9330f7f6f3c53127592c80a6c16e16d4078 Mon Sep 17 00:00:00 2001 From: Martin Simka Date: Wed, 14 Jan 2015 13:47:05 +0100 Subject: [PATCH] HHH-9568 : EntityManager.flush() does not behave properly with transient one-to-one association and no cascade (test case) (cherry picked from commit 6b4260413928e86625b1f6f3d78de27b4583d423) --- .../org/hibernate/jpa/test/cascade/A.java | 51 +++++++++++++++++ .../org/hibernate/jpa/test/cascade/B.java | 56 +++++++++++++++++++ .../jpa/test/cascade/CascadeTest.java | 31 +++++++++- 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/A.java create mode 100644 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/B.java diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/A.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/A.java new file mode 100644 index 0000000000..45bfac2758 --- /dev/null +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/A.java @@ -0,0 +1,51 @@ +//$Id$ +package org.hibernate.jpa.test.cascade; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import java.io.Serializable; + +/** + * @author Martin Simka + */ +@Entity +public class A implements Serializable { + private Integer id; + private B b; + + @Id + @GeneratedValue + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne(targetEntity=B.class, mappedBy="a", orphanRemoval = true) + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + + public boolean equals(Object o) { + if ( this == o ) return true; + if ( !( o instanceof A) ) return false; + + final A a = (A) o; + + if ( !id.equals( a.id ) ) return false; + + return true; + } + + public int hashCode() { + return id.hashCode(); + } +} diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/B.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/B.java new file mode 100644 index 0000000000..c5b1a55ded --- /dev/null +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/B.java @@ -0,0 +1,56 @@ +//$Id$ +package org.hibernate.jpa.test.cascade; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; +import java.io.Serializable; + +/** + * @author Martin Simka + */ +@Entity +public class B implements Serializable { + private Integer id; + private A a; + + @Id + @GeneratedValue + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne(targetEntity=A.class, cascade=CascadeType.ALL,optional = true, orphanRemoval = true) + @JoinColumn(name="FK_FOR_B") + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + public boolean equals(Object o) { + if ( this == o ) return true; + if ( !( o instanceof B) ) return false; + + final B b = (B) o; + + if ( !id.equals( b.id ) ) return false; + + return true; + } + + public int hashCode() { + return id.hashCode(); + } +} diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/CascadeTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/CascadeTest.java index cac652d542..0315c46bb8 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/CascadeTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/cascade/CascadeTest.java @@ -26,10 +26,15 @@ package org.hibernate.jpa.test.cascade; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; +import org.hibernate.testing.FailureExpected; +import org.hibernate.testing.TestForIssue; import org.junit.Test; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * @author Max Rydahl Andersen */ @@ -99,13 +104,37 @@ public class CascadeTest extends BaseEntityManagerFunctionalTestCase { em.close(); } + @Test + @TestForIssue(jiraKey = "HHH-9568") + @FailureExpected(jiraKey = "HHH-9568") + public void testFlushTransientOneToOne() throws Exception { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + + B b = new B(); + A a = new A(); + + a.setB(b); + try { + em.persist(a); + em.flush(); + em.getTransaction().commit(); + fail("should have raised an IllegalStateException"); + } catch (IllegalStateException ex) { + // IllegalStateException caught as expected + } + em.close(); + } + @Override public Class[] getAnnotatedClasses() { return new Class[]{ Teacher.class, Student.class, Song.class, - Author.class + Author.class, + A.class, + B.class }; }