HHH-8580 clearing a map collection caused NPE

This commit is contained in:
Brett Meyer 2013-10-04 11:40:41 -04:00
parent 075bc86209
commit ca3b22a18c
3 changed files with 85 additions and 9 deletions

View File

@ -208,7 +208,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
while ( entries.hasNext() ) { while ( entries.hasNext() ) {
final Object entry = entries.next(); final Object entry = entries.next();
if ( collection.entryExists( entry, i ) ) { if ( entry != null && collection.entryExists( entry, i ) ) {
int offset = 1; int offset = 1;
PreparedStatement st = null; PreparedStatement st = null;
boolean callable = isUpdateCallable(); boolean callable = isUpdateCallable();

View File

@ -364,6 +364,10 @@ public class OrderByTest extends BaseCoreFunctionalTestCase {
catch ( SQLException e ) { catch ( SQLException e ) {
fail(e.getMessage()); fail(e.getMessage());
} }
finally {
s.getTransaction().rollback();
s.close();
}
} }
@Test @Test

View File

@ -22,30 +22,49 @@
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.test.collection.map; 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.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; 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}. * Test various situations using a {@link PersistentMap}.
* *
* @author Steve Ebersole * @author Steve Ebersole
* @author Brett Meyer
*/ */
public class PersistentMapTest extends BaseCoreFunctionalTestCase { public class PersistentMapTest extends BaseCoreFunctionalTestCase {
@Override @Override
public String[] getMappings() { public String[] getMappings() {
return new String[] { "collection/map/Mappings.hbm.xml" }; return new String[] { "collection/map/Mappings.hbm.xml" };
} }
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { User.class, UserData.class };
}
@Test @Test
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
@ -157,4 +176,57 @@ public class PersistentMapTest extends BaseCoreFunctionalTestCase {
session.getTransaction().commit(); session.getTransaction().commit();
session.close(); 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<String, UserData> userDatas = new HashMap<String, UserData>();
}
@Entity
private static class UserData {
@Id @GeneratedValue
private Integer id;
@ManyToOne
@JoinColumn(name = "userId")
private User user;
}
} }