HHH-9230 - NullPointer when combining JPQL query with in clause and @NamedEntityGraph
This commit is contained in:
parent
9390062abc
commit
287a516760
|
@ -33,6 +33,7 @@ import org.hibernate.Query;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.query.spi.EntityGraphQueryHint;
|
||||||
import org.hibernate.engine.query.spi.HQLQueryPlan;
|
import org.hibernate.engine.query.spi.HQLQueryPlan;
|
||||||
import org.hibernate.engine.query.spi.ParameterMetadata;
|
import org.hibernate.engine.query.spi.ParameterMetadata;
|
||||||
import org.hibernate.engine.spi.QueryParameters;
|
import org.hibernate.engine.spi.QueryParameters;
|
||||||
|
@ -1026,11 +1027,25 @@ public abstract class AbstractQueryImpl implements Query {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HQLQueryPlan getQueryPlan() {
|
|
||||||
return queryPlan;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQueryPlan(HQLQueryPlan queryPlan) {
|
/**
|
||||||
this.queryPlan = queryPlan;
|
* Used from HEM code as a (hopefully temporary) means to apply a custom query plan
|
||||||
|
* in regards to a JPA entity graph.
|
||||||
|
*
|
||||||
|
* @param hint The entity graph hint object
|
||||||
|
*/
|
||||||
|
public void applyEntityGraphQueryHint(EntityGraphQueryHint hint) {
|
||||||
|
verifyParameters();
|
||||||
|
// todo : likely need to update the instance state related to queryString and parameters
|
||||||
|
final Map namedParams = getNamedParams();
|
||||||
|
final String expandedQuery = expandParameterLists( namedParams );
|
||||||
|
this.queryPlan = new HQLQueryPlan(
|
||||||
|
expandedQuery,
|
||||||
|
false,
|
||||||
|
session.getLoadQueryInfluencers().getEnabledFilters(),
|
||||||
|
session.getFactory(),
|
||||||
|
hint
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -553,16 +553,8 @@ public class QueryImpl<X> extends AbstractQueryImpl<X>
|
||||||
|
|
||||||
private List<X> list() {
|
private List<X> list() {
|
||||||
if ( getEntityGraphQueryHint() != null ) {
|
if ( getEntityGraphQueryHint() != null ) {
|
||||||
SessionImplementor sessionImpl = (SessionImplementor) getEntityManager().getSession();
|
|
||||||
HQLQueryPlan entityGraphQueryPlan = new HQLQueryPlan(
|
|
||||||
getHibernateQuery().getQueryString(),
|
|
||||||
false,
|
|
||||||
sessionImpl.getLoadQueryInfluencers().getEnabledFilters(),
|
|
||||||
sessionImpl.getFactory(),
|
|
||||||
getEntityGraphQueryHint()
|
|
||||||
);
|
|
||||||
// Safe to assume QueryImpl at this point.
|
// Safe to assume QueryImpl at this point.
|
||||||
unwrap( org.hibernate.internal.QueryImpl.class ).setQueryPlan( entityGraphQueryPlan );
|
unwrap( org.hibernate.internal.QueryImpl.class ).applyEntityGraphQueryHint( getEntityGraphQueryHint() );
|
||||||
}
|
}
|
||||||
return query.list();
|
return query.list();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.jpa.test.query;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.NamedAttributeNode;
|
||||||
|
import javax.persistence.NamedEntityGraph;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Based on the test developed by Hans Desmet to reproduce the bug reported in HHH-9230
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-9230")
|
||||||
|
public class QueryWithInParamListAndNamedEntityGraphTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] {Person.class};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInClause() {
|
||||||
|
// this test works
|
||||||
|
EntityManager em = getOrCreateEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
Set<Long> ids = new HashSet<Long>();
|
||||||
|
ids.add( 1L );
|
||||||
|
ids.add( 2L );
|
||||||
|
TypedQuery<Person> query = em.createQuery( "select p from Person p where p.id in :ids", Person.class );
|
||||||
|
query.setParameter( "ids", ids );
|
||||||
|
query.getResultList();
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntityGraph() {
|
||||||
|
// this test works
|
||||||
|
EntityManager em = getOrCreateEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
TypedQuery<Person> query = em.createQuery( "select p from Person p", Person.class );
|
||||||
|
query.setHint( "javax.persistence.loadgraph", em.createEntityGraph( "withBoss" ) );
|
||||||
|
query.getResultList();
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntityGraphAndInClause() {
|
||||||
|
// this test fails
|
||||||
|
EntityManager em = getOrCreateEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
Set<Long> ids = new HashSet<Long>();
|
||||||
|
ids.add( 1L );
|
||||||
|
ids.add( 2L );
|
||||||
|
TypedQuery<Person> query = em.createQuery( "select p from Person p where p.id in :ids", Person.class );
|
||||||
|
query.setHint( "javax.persistence.loadgraph", em.createEntityGraph( "withBoss" ) );
|
||||||
|
query.setParameter( "ids", ids );
|
||||||
|
query.getResultList();
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Person")
|
||||||
|
@Table(name = "Person")
|
||||||
|
@NamedEntityGraph(name = "withBoss", attributeNodes = @NamedAttributeNode("boss"))
|
||||||
|
public static class Person {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn
|
||||||
|
private Person boss;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue