impl the new overload of createNativeQuery()
- and add a second new overload - tolerate non-entity classes as arguments to these methods - the overloads accept a result class, and return a typed Query<R>
This commit is contained in:
parent
4ea59b4961
commit
ac845bca31
|
@ -511,11 +511,21 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
|||
return queryDelegate().createNativeQuery( sqlString, resultClass );
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass, String tableAlias) {
|
||||
return queryDelegate().createNativeQuery( sqlString, resultClass, tableAlias );
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("rawtypes")
|
||||
public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName) {
|
||||
return queryDelegate().createNativeQuery( sqlString, resultSetMappingName );
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName, Class resultClass) {
|
||||
return queryDelegate().createNativeQuery( sqlString, resultSetMappingName, resultClass );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureCall createNamedStoredProcedureQuery(String name) {
|
||||
return delegate.createNamedStoredProcedureQuery( name );
|
||||
|
|
|
@ -692,59 +692,69 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
}
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings({"rawtypes", "unchecked"})
|
||||
//note: we're doing something a bit funny here to work around
|
||||
// the classing signatures declared by the supertypes
|
||||
public NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass) {
|
||||
checkOpen();
|
||||
pulseTransactionCoordinator();
|
||||
delayedAfterCompletion();
|
||||
|
||||
try {
|
||||
NativeQueryImplementor query = createNativeQuery( sqlString );
|
||||
if ( Tuple.class.equals( resultClass ) ) {
|
||||
query.setTupleTransformer( new NativeQueryTupleTransformer() );
|
||||
}
|
||||
else {
|
||||
query.addEntity( "alias1", resultClass.getName(), LockMode.READ );
|
||||
}
|
||||
return query;
|
||||
}
|
||||
catch (RuntimeException he) {
|
||||
throw getExceptionConverter().convert( he );
|
||||
}
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("rawtypes")
|
||||
public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName) {
|
||||
checkOpen();
|
||||
pulseTransactionCoordinator();
|
||||
delayedAfterCompletion();
|
||||
|
||||
final NativeQueryImplementor<Object> query;
|
||||
try {
|
||||
if ( StringHelper.isNotEmpty( resultSetMappingName ) ) {
|
||||
if ( StringHelper.isNotEmpty(resultSetMappingName) ) {
|
||||
final NamedResultSetMappingMemento resultSetMappingMemento = getFactory().getQueryEngine()
|
||||
.getNamedObjectRepository()
|
||||
.getResultSetMappingMemento( resultSetMappingName );
|
||||
.getResultSetMappingMemento(resultSetMappingName);
|
||||
|
||||
if ( resultSetMappingMemento == null ) {
|
||||
throw new HibernateException( "Could not resolve specified result-set mapping name : " + resultSetMappingName );
|
||||
throw new HibernateException( "Could not resolve specified result-set mapping name : "
|
||||
+ resultSetMappingName);
|
||||
}
|
||||
|
||||
query = new NativeQueryImpl<>( sqlString, resultSetMappingMemento, this );
|
||||
return new NativeQueryImpl<>(sqlString, resultSetMappingMemento, this);
|
||||
}
|
||||
else {
|
||||
query = new NativeQueryImpl<>( sqlString, this );
|
||||
return new NativeQueryImpl<>(sqlString, this);
|
||||
}
|
||||
//TODO: why no applyQuerySettingsAndHints( query ); ???
|
||||
}
|
||||
catch (RuntimeException he) {
|
||||
throw getExceptionConverter().convert( he );
|
||||
}
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings({"rawtypes", "unchecked"})
|
||||
//note: we're doing something a bit funny here to work around
|
||||
// the clashing signatures declared by the supertypes
|
||||
public NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass) {
|
||||
NativeQueryImplementor query = createNativeQuery( sqlString );
|
||||
if ( Tuple.class.equals(resultClass) ) {
|
||||
query.setTupleTransformer( new NativeQueryTupleTransformer() );
|
||||
}
|
||||
else if ( getFactory().getMetamodel().findEntityDescriptor(resultClass)!=null ) {
|
||||
query.addEntity( "alias1", resultClass.getName(), LockMode.READ );
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass, String tableAlias) {
|
||||
NativeQueryImplementor query = createNativeQuery( sqlString );
|
||||
if ( Tuple.class.equals(resultClass) ) {
|
||||
query.setTupleTransformer( new NativeQueryTupleTransformer() );
|
||||
}
|
||||
else if ( getFactory().getMetamodel().findEntityDescriptor(resultClass)!=null ) {
|
||||
query.addEntity( tableAlias, resultClass.getName(), LockMode.READ );
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName, Class resultClass) {
|
||||
final NativeQueryImplementor query = createNativeQuery( sqlString, resultSetMappingName );
|
||||
if ( Tuple.class.equals( resultClass ) ) {
|
||||
query.setTupleTransformer( new NativeQueryTupleTransformer() );
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// named query handling
|
||||
|
|
|
@ -98,6 +98,9 @@ public interface QueryProducer {
|
|||
/**
|
||||
* Create a NativeQuery instance for the given native (SQL) query using
|
||||
* implicit mapping to the specified Java type.
|
||||
* <p>
|
||||
* If the given class is an entity class, this method is equivalent to
|
||||
* {@code createNativeQuery(sqlString).addEntity("alias1", resultClass)}.
|
||||
*
|
||||
* @param sqlString Native (SQL) query string
|
||||
* @param resultClass The Java entity type to map results to
|
||||
|
@ -108,6 +111,23 @@ public interface QueryProducer {
|
|||
*/
|
||||
<R> NativeQuery<R> createNativeQuery(String sqlString, Class<R> resultClass);
|
||||
|
||||
/**
|
||||
* Create a NativeQuery instance for the given native (SQL) query using
|
||||
* implicit mapping to the specified Java type.
|
||||
* <p>
|
||||
* If the given class is an entity class, this method is equivalent to
|
||||
* {@code createNativeQuery(sqlString).addEntity(tableAlias, resultClass)}.
|
||||
*
|
||||
* @param sqlString Native (SQL) query string
|
||||
* @param resultClass The Java entity type to map results to
|
||||
* @param tableAlias The table alias for columns in the result set
|
||||
*
|
||||
* @return The NativeQuery instance for manipulation and execution
|
||||
*
|
||||
* @see jakarta.persistence.EntityManager#createNativeQuery(String,Class)
|
||||
*/
|
||||
<R> NativeQuery<R> createNativeQuery(String sqlString, Class<R> resultClass, String tableAlias);
|
||||
|
||||
/**
|
||||
* Create a NativeQuery instance for the given native (SQL) query using
|
||||
* implicit mapping to the specified Java type.
|
||||
|
|
|
@ -50,9 +50,15 @@ public interface QueryProducerImplementor extends QueryProducer {
|
|||
@Override
|
||||
<R> NativeQueryImplementor<R> createNativeQuery(String sqlString, Class<R> resultClass);
|
||||
|
||||
@Override
|
||||
<R> NativeQueryImplementor<R> createNativeQuery(String sqlString, Class<R> resultClass, String tableAlias);
|
||||
|
||||
@Override @SuppressWarnings("rawtypes")
|
||||
NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName);
|
||||
|
||||
@Override
|
||||
<R> NativeQueryImplementor<R> createNativeQuery(String sqlString, String resultSetMappingName, Class<R> resultClass);
|
||||
|
||||
@Override @SuppressWarnings("rawtypes")
|
||||
NativeQueryImplementor getNamedNativeQuery(String name);
|
||||
|
||||
|
|
|
@ -99,11 +99,11 @@ public class QueryAndSQLTest {
|
|||
.currentDate();
|
||||
|
||||
String sql = String.format(
|
||||
"select t.TABLE_NAME as {t.tableName}, %s as {t.daysOld} from ALL_TABLES t where t.TABLE_NAME = 'AUDIT_ACTIONS' ",
|
||||
"select t.TABLE_NAME as {t.tableName}, %s as {t.daysOld} from ALL_TABLES t where t.TABLE_NAME = 'AUDIT_ACTIONS' ",
|
||||
dateFunctionRendered
|
||||
);
|
||||
String sql2 = String.format(
|
||||
"select TABLE_NAME as t_name, %s as t_time from ALL_TABLES where TABLE_NAME = 'AUDIT_ACTIONS' ",
|
||||
"select TABLE_NAME as t_name, %s as t_time from ALL_TABLES where TABLE_NAME = 'AUDIT_ACTIONS' ",
|
||||
dateFunctionRendered
|
||||
);
|
||||
|
||||
|
@ -111,7 +111,9 @@ public class QueryAndSQLTest {
|
|||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createNativeQuery( sql ).addEntity( "t", AllTables.class ).list();
|
||||
List<AllTables> allTables = session.createNativeQuery( sql, AllTables.class, "t" ).list();
|
||||
session.createNativeQuery( sql2, "all" ).list();
|
||||
List<String> allTableNames = session.createNativeQuery( sql2, "all", String.class ).list();
|
||||
NativeQuery q = session.createNativeQuery( sql2 );
|
||||
q.addRoot( "t", AllTables.class ).addProperty( "tableName", "t_name" ).addProperty(
|
||||
"daysOld",
|
||||
|
|
|
@ -81,6 +81,19 @@ public class QueryTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
} );
|
||||
}
|
||||
|
||||
public void testNativeQueryResultWithResultClass() {
|
||||
inTransaction( (session) -> {
|
||||
final NativeQueryImplementor<Object[]> query = session.createNativeQuery( "select id, salary from EMP", "emp_id_salary", Object[].class );
|
||||
|
||||
final List<Object[]> results = query.list();
|
||||
assertThat( results ).hasSize( 1 );
|
||||
|
||||
final Object[] values = results.get( 0 );
|
||||
assertThat( values[0] ).isEqualTo( 1 );
|
||||
assertThat( values[1] ).isEqualTo( SALARY );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( jiraKey = "HHH-14975", message = "Not yet implemented" )
|
||||
@NotImplementedYet
|
||||
|
|
|
@ -75,7 +75,7 @@ public class FormulaNativeQueryTest {
|
|||
public void testNativeQueryWithAllFields(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Query query = session.createNativeQuery(
|
||||
Query<Foo> query = session.createNativeQuery(
|
||||
"SELECT ft.*, abs(locationEnd - locationStart) as distance FROM foo_table ft",
|
||||
Foo.class
|
||||
);
|
||||
|
|
|
@ -171,6 +171,28 @@ public class EntityResultTests extends AbstractUsageTest {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitDiscriminatedMappingWithResultClass(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final String qryString =
|
||||
"select id as id_alias,"
|
||||
+ " type_code as type_code_alias,"
|
||||
+ " root_name as root_name_alias,"
|
||||
+ " subtype1_name as sub_type1_name_alias,"
|
||||
+ " subtype2_name as sub_type2_name_alias"
|
||||
+ " from discriminated_entity";
|
||||
|
||||
final List<DiscriminatedRoot> results = session.createNativeQuery( qryString, "root-explicit", DiscriminatedRoot.class ).list();
|
||||
assertThat( results.size(), is( 4 ) );
|
||||
|
||||
final Set<Integer> idsFound = new HashSet<>();
|
||||
results.forEach( result -> idsFound.add( result.getId() ) );
|
||||
assertThat( idsFound, containsInAnyOrder( 1, 2, 3, 4 ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertedAttributes(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
|
|
|
@ -49,7 +49,6 @@ import org.hibernate.testing.orm.junit.SessionFactory;
|
|||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.PersistenceException;
|
||||
|
@ -260,6 +259,34 @@ public class NativeSQLQueriesTest {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultSetMappingDefinitionWithResultClass(SessionFactoryScope scope) {
|
||||
Organization ifa = new Organization("IFA");
|
||||
Organization jboss = new Organization("JBoss");
|
||||
Person gavin = new Person("Gavin");
|
||||
Employment emp = new Employment(gavin, jboss, "AU");
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.persist(ifa);
|
||||
session.persist(jboss);
|
||||
session.persist(gavin);
|
||||
session.persist(emp);
|
||||
|
||||
List<Object[]> l = session.createNativeQuery( getOrgEmpRegionSQL(), "org-emp-regionCode", Object[].class ).list();
|
||||
assertEquals( l.size(), 2 );
|
||||
|
||||
l = session.createNativeQuery( getOrgEmpPersonSQL(), "org-emp-person", Object[].class ).list();
|
||||
assertEquals( l.size(), 1 );
|
||||
|
||||
session.delete(emp);
|
||||
session.delete(gavin);
|
||||
session.delete(ifa);
|
||||
session.delete(jboss);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScalarValues(SessionFactoryScope scope) throws Exception {
|
||||
Organization ifa = new Organization( "IFA" );
|
||||
|
|
Loading…
Reference in New Issue