From bc99f16b8e821e67f424862e75f8697a63093726 Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Fri, 4 Oct 2013 11:40:41 -0400 Subject: [PATCH] HHH-8580 clearing a map collection caused NPE --- .../collection/OneToManyPersister.java | 2 +- .../annotations/onetomany/OrderByTest.java | 4 + .../collection/map/PersistentMapTest.java | 88 +++++++++++++++++-- 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java index ed4046f38b..2da0fe4a3b 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java @@ -208,7 +208,7 @@ public class OneToManyPersister extends AbstractCollectionPersister { while ( entries.hasNext() ) { final Object entry = entries.next(); - if ( collection.entryExists( entry, i ) ) { + if ( entry != null && collection.entryExists( entry, i ) ) { int offset = 1; PreparedStatement st = null; boolean callable = isUpdateCallable(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java index 15aa425284..3cf9942035 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java @@ -364,6 +364,10 @@ public class OrderByTest extends BaseCoreFunctionalTestCase { catch ( SQLException e ) { fail(e.getMessage()); } + finally { + s.getTransaction().rollback(); + s.close(); + } } @Test diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/map/PersistentMapTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/map/PersistentMapTest.java index 5d228b7500..28665abbbb 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/map/PersistentMapTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/collection/map/PersistentMapTest.java @@ -22,30 +22,49 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.test.collection.map; -import java.util.HashMap; - -import org.junit.Test; - -import org.hibernate.Session; -import org.hibernate.collection.internal.PersistentMap; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +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.MapKeyColumn; +import javax.persistence.OneToMany; + +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.collection.internal.PersistentMap; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + /** * Test various situations using a {@link PersistentMap}. * * @author Steve Ebersole + * @author Brett Meyer */ public class PersistentMapTest extends BaseCoreFunctionalTestCase { @Override public String[] getMappings() { return new String[] { "collection/map/Mappings.hbm.xml" }; } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { User.class, UserData.class }; + } @Test @SuppressWarnings({ "unchecked" }) @@ -157,4 +176,57 @@ public class PersistentMapTest extends BaseCoreFunctionalTestCase { session.getTransaction().commit(); session.close(); } + + @Test + @TestForIssue(jiraKey = "HHH-5732") + public void testClearMap() { + Session s = openSession(); + s.beginTransaction(); + + User user = new User(); + UserData userData = new UserData(); + userData.user = user; + user.userDatas.put( "foo", userData ); + s.persist( user ); + + s.getTransaction().commit(); + s.clear(); + + s.beginTransaction(); + + user = (User) s.get( User.class, 1 ); + user.userDatas.clear(); + s.update( user ); + Query q = s.createQuery( "DELETE FROM " + UserData.class.getName() + " d WHERE d.user = :user" ); + q.setParameter( "user", user ); + q.executeUpdate(); + + s.getTransaction().commit(); + s.clear(); + + assertEquals( ( (User) s.get( User.class, user.id ) ).userDatas.size(), 0 ); + assertEquals( s.createQuery( "FROM " + UserData.class.getName() ).list().size(), 0 ); + + s.close(); + } + + @Entity + private static class User implements Serializable { + @Id @GeneratedValue + private Integer id; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL) + @MapKeyColumn(name = "name", nullable = true) + private Map userDatas = new HashMap(); + } + + @Entity + private static class UserData { + @Id @GeneratedValue + private Integer id; + + @ManyToOne + @JoinColumn(name = "userId") + private User user; + } }