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
This commit is contained in:
parent
53c075ed0c
commit
9a31ee44bf
|
@ -374,7 +374,7 @@ public class SQLQueryReturnProcessor {
|
||||||
alias2CollectionSuffix.put( alias, suffix );
|
alias2CollectionSuffix.put( alias, suffix );
|
||||||
collectionPropertyResultMaps.put( alias, propertyResults );
|
collectionPropertyResultMaps.put( alias, propertyResults );
|
||||||
|
|
||||||
if ( collectionPersister.isOneToMany() ) {
|
if ( collectionPersister.isOneToMany() || collectionPersister.isManyToMany() ) {
|
||||||
SQLLoadable persister = ( SQLLoadable ) collectionPersister.getElementPersister();
|
SQLLoadable persister = ( SQLLoadable ) collectionPersister.getElementPersister();
|
||||||
addPersister( alias, filter( propertyResults ), persister );
|
addPersister( alias, filter( propertyResults ), persister );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
package org.hibernate.test.sql.hand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class Person {
|
public class Person {
|
||||||
private long id;
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
public Person(String name) {
|
public Person(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Person() {}
|
public Person() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the id.
|
* @return Returns the id.
|
||||||
*/
|
*/
|
||||||
public long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id The id to set.
|
* @param id The id to set.
|
||||||
*/
|
*/
|
||||||
public void setId(long id) {
|
public void setId(Long id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the name.
|
* @return Returns the name.
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param name The name to set.
|
* @param name The name to set.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -31,6 +31,19 @@
|
||||||
|
|
||||||
</class>
|
</class>
|
||||||
|
|
||||||
|
<class name="Group" table="GROUPP">
|
||||||
|
<id name="id" unsaved-value="0" column="ID">
|
||||||
|
<generator class="increment"/>
|
||||||
|
</id>
|
||||||
|
<property name="name" column="NAME" not-null="true"/>
|
||||||
|
<list name="persons" table="GROUP_PERSON"
|
||||||
|
cascade="none" inverse="false" lazy="true">
|
||||||
|
<key column="GROUP_ID" />
|
||||||
|
<list-index column="POS" />
|
||||||
|
<many-to-many class="Person" column="PERSON_ID" />
|
||||||
|
</list>
|
||||||
|
</class>
|
||||||
|
|
||||||
<class name="Employment" table="EMPLOYMENT">
|
<class name="Employment" table="EMPLOYMENT">
|
||||||
<id name="employmentId" unsaved-value="0" column="EMPID">
|
<id name="employmentId" unsaved-value="0" column="EMPID">
|
||||||
<generator class="increment"/>
|
<generator class="increment"/>
|
||||||
|
@ -259,4 +272,31 @@
|
||||||
LEFT OUTER JOIN EMPLOYMENT emp ON org.ORGID = emp.EMPLOYER
|
LEFT OUTER JOIN EMPLOYMENT emp ON org.ORGID = emp.EMPLOYER
|
||||||
</sql-query>
|
</sql-query>
|
||||||
|
|
||||||
|
<sql-query name="manyToManyFetch">
|
||||||
|
<![CDATA[
|
||||||
|
SELECT groupp.ID as group_id,
|
||||||
|
groupp.NAME as group_name,
|
||||||
|
group_person.PERSON_ID as group_person_personId,
|
||||||
|
group_person.GROUP_ID as group_person_groupId,
|
||||||
|
group_person.POS as group_person_pos,
|
||||||
|
person.PERID as person_id,
|
||||||
|
person.NAME as person_name
|
||||||
|
FROM GROUPP groupp,
|
||||||
|
GROUP_PERSON group_person,
|
||||||
|
PERSON person
|
||||||
|
WHERE groupp.ID = group_person.GROUP_ID
|
||||||
|
and person.PERID = group_person.PERSON_ID
|
||||||
|
]]>
|
||||||
|
<return alias="groupp" class="Group">
|
||||||
|
<return-property name="id" column="group_id" />
|
||||||
|
<return-property name="name" column="group_name" />
|
||||||
|
</return>
|
||||||
|
<return-join alias="group_person" property="groupp.persons">
|
||||||
|
<return-property name="key" column="group_person_groupId" />
|
||||||
|
<return-property name="index" column="group_person_pos" />
|
||||||
|
<return-property name="element" column="person_id" />
|
||||||
|
<return-property name="element.id" column="person_id" />
|
||||||
|
<return-property name="element.name" column="person_name" />
|
||||||
|
</return-join>
|
||||||
|
</sql-query>
|
||||||
</hibernate-mapping>
|
</hibernate-mapping>
|
|
@ -14,21 +14,22 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.Query;
|
import org.hibernate.Query;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
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.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.junit.functional.FunctionalTestCase;
|
import org.hibernate.junit.functional.FunctionalTestCase;
|
||||||
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
|
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.DistinctRootEntityResultTransformer;
|
||||||
import org.hibernate.transform.Transformers;
|
import org.hibernate.transform.Transformers;
|
||||||
import org.hibernate.transform.AliasToEntityMapResultTransformer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests of various features of native SQL queries.
|
* 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 {
|
private static class UpperCasedAliasToEntityMapResultTransformer extends AliasToEntityMapResultTransformer {
|
||||||
public Object transformTuple(Object[] tuple, String[] aliases) {
|
public Object transformTuple(Object[] tuple, String[] aliases) {
|
||||||
String[] ucAliases = new String[aliases.length];
|
String[] ucAliases = new String[aliases.length];
|
||||||
|
|
Loading…
Reference in New Issue