From 9a31ee44bfb26761bfe5b92a7611f958e424af30 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 11 May 2009 21:15:24 +0000 Subject: [PATCH] HHH-2745 - NullPointerException when eager fetching joined many-to-many with native SQL query git-svn-id: https://svn.jboss.org/repos/hibernate/core/branches/Branch_3_2@16537 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../custom/sql/SQLQueryReturnProcessor.java | 2 +- test/org/hibernate/test/sql/hand/Group.java | 42 ++++++++++ test/org/hibernate/test/sql/hand/Person.java | 40 ++++++++-- .../sql/hand/query/NativeSQLQueries.hbm.xml | 40 ++++++++++ .../sql/hand/query/NativeSQLQueriesTest.java | 76 ++++++++++++++++--- 5 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 test/org/hibernate/test/sql/hand/Group.java diff --git a/src/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java b/src/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java index 51875b54eb..1deed44ad0 100644 --- a/src/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java +++ b/src/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java @@ -374,7 +374,7 @@ public class SQLQueryReturnProcessor { alias2CollectionSuffix.put( alias, suffix ); collectionPropertyResultMaps.put( alias, propertyResults ); - if ( collectionPersister.isOneToMany() ) { + if ( collectionPersister.isOneToMany() || collectionPersister.isManyToMany() ) { SQLLoadable persister = ( SQLLoadable ) collectionPersister.getElementPersister(); addPersister( alias, filter( propertyResults ), persister ); } diff --git a/test/org/hibernate/test/sql/hand/Group.java b/test/org/hibernate/test/sql/hand/Group.java new file mode 100644 index 0000000000..ff636f94fb --- /dev/null +++ b/test/org/hibernate/test/sql/hand/Group.java @@ -0,0 +1,42 @@ +package org.hibernate.test.sql.hand; + +import java.util.ArrayList; +import java.util.List; + +public class Group { + private Long id; + private List persons = new ArrayList(); + private String name; + + public Group() { + } + + public Group(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public List getPersons() { + return persons; + } + + public void setPersons(List persons) { + this.persons = persons; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/test/org/hibernate/test/sql/hand/Person.java b/test/org/hibernate/test/sql/hand/Person.java index c91b5a1a46..96609a54eb 100644 --- a/test/org/hibernate/test/sql/hand/Person.java +++ b/test/org/hibernate/test/sql/hand/Person.java @@ -1,37 +1,61 @@ -//$Id: Person.java 4316 2004-08-14 13:12:03Z oneovthafew $ +/* + * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ package org.hibernate.test.sql.hand; /** * @author Gavin King */ public class Person { - private long id; + private Long id; private String name; public Person(String name) { this.name = name; } - - public Person() {} - -/** + + public Person() { + } + + /** * @return Returns the id. */ - public long getId() { + public Long getId() { return id; } + /** * @param id The id to set. */ - public void setId(long id) { + public void setId(Long id) { this.id = id; } + /** * @return Returns the name. */ public String getName() { return name; } + /** * @param name The name to set. */ diff --git a/test/org/hibernate/test/sql/hand/query/NativeSQLQueries.hbm.xml b/test/org/hibernate/test/sql/hand/query/NativeSQLQueries.hbm.xml index 4d42100b26..bcae868bf0 100644 --- a/test/org/hibernate/test/sql/hand/query/NativeSQLQueries.hbm.xml +++ b/test/org/hibernate/test/sql/hand/query/NativeSQLQueries.hbm.xml @@ -31,6 +31,19 @@ + + + + + + + + + + + + @@ -259,4 +272,31 @@ LEFT OUTER JOIN EMPLOYMENT emp ON org.ORGID = emp.EMPLOYER + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java b/test/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java index 826e8430dc..d9cb937ec5 100644 --- a/test/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java +++ b/test/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java @@ -14,21 +14,22 @@ import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.test.sql.hand.Organization; -import org.hibernate.test.sql.hand.Person; -import org.hibernate.test.sql.hand.Employment; -import org.hibernate.test.sql.hand.Product; -import org.hibernate.test.sql.hand.Order; -import org.hibernate.test.sql.hand.Dimension; -import org.hibernate.test.sql.hand.SpaceShip; -import org.hibernate.test.sql.hand.Speech; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.junit.functional.FunctionalTestCase; import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.test.sql.hand.Dimension; +import org.hibernate.test.sql.hand.Employment; +import org.hibernate.test.sql.hand.Group; +import org.hibernate.test.sql.hand.Order; +import org.hibernate.test.sql.hand.Organization; +import org.hibernate.test.sql.hand.Person; +import org.hibernate.test.sql.hand.Product; +import org.hibernate.test.sql.hand.SpaceShip; +import org.hibernate.test.sql.hand.Speech; +import org.hibernate.transform.AliasToEntityMapResultTransformer; import org.hibernate.transform.DistinctRootEntityResultTransformer; import org.hibernate.transform.Transformers; -import org.hibernate.transform.AliasToEntityMapResultTransformer; /** * Tests of various features of native SQL queries. @@ -608,6 +609,63 @@ public class NativeSQLQueriesTest extends FunctionalTestCase { } } + public void testAddJoinForManyToMany() { + Session s = openSession(); + Transaction t = s.beginTransaction(); + Person gavin = new Person( "Gavin" ); + Person max = new Person( "Max" ); + Person pete = new Person( "Pete" ); + + Group hibernate = new Group( "Hibernate" ); + Group seam = new Group( "Seam" ); + + s.persist( gavin ); + s.persist( max ); + s.persist( pete ); + s.persist( seam ); + s.persist( hibernate ); + + hibernate.getPersons().add( gavin ); + hibernate.getPersons().add( max ); + seam.getPersons().add( gavin ); + seam.getPersons().add( pete ); + + s.flush(); + s.clear(); + + // todo : see http://opensource.atlassian.com/projects/hibernate/browse/HHH-3908 +// String sqlStr = "SELECT {groupp.*} , {gp.*} " + +// "FROM GROUPP groupp, GROUP_PERSON gp, PERSON person WHERE groupp.ID = gp.GROUP_ID and person.PERID = gp.PERSON_ID"; +// +// List l = s.createSQLQuery( sqlStr ) +// .addEntity("groupp", Group.class) +// .addJoin("gp","groupp.persons") +// .list(); + List l = s.getNamedQuery( "manyToManyFetch" ).list(); + //assertEquals( 2, l.size() ); + + t.commit(); + s.close(); + + s = openSession(); + t = s.beginTransaction(); + + seam.getPersons().remove( gavin ); + seam.getPersons().remove( pete ); + + hibernate.getPersons().remove( gavin ); + hibernate.getPersons().remove( max ); + + s.delete( seam ); + s.delete( hibernate ); + s.delete( gavin ); + s.delete( max ); + s.delete( pete ); + + t.commit(); + s.close(); + } + private static class UpperCasedAliasToEntityMapResultTransformer extends AliasToEntityMapResultTransformer { public Object transformTuple(Object[] tuple, String[] aliases) { String[] ucAliases = new String[aliases.length];