I am developing an application using Spring and Hibernate. I am wondering why there are two separate methods getNamedQuery(String name) and createNamedQuery(String name).
I checked Javadoc here and found the description to be similar except createNamedQuery accepts native sql (there're separate methods createNativeQuery, getNamedNativeQuery, getNamedSQLQuery to create native queries).
I want to understand whether there is any other fundamental difference that makes my queries faster/slower.
getNamedQuery:
Query getNamedQuery(String queryName) Create a Query instance for the named query. Parameters: queryName - the name of a pre-defined, named query Returns: The Query instance for manipulation and execution Throws: IllegalArgumentException - if a query has not been defined with the given name or if the query string is found to be invalid
createNamedQuery:
Query createNamedQuery(String name) The JPA-defined named query creation method. This form can represent an HQL/JPQL query or a native query. Parameters: name - the name of a pre-defined, named query Returns: The Query instance for manipulation and execution Throws: IllegalArgumentException - if a query has not been defined with the given name or if the query string is found to be invalid See Also: EntityManager.createNamedQuery(String)
TL;DR
The two methods perform (except some minor things) the same processings : try to execute a named JPQL or SQL query with the almost same logic.
Your remark is good as the javadoc of these methods should be almost the same while these differ.
Query getNamedQuery(String queryName);
Create a Query instance for the named query.
Parameters:
queryName the name of a pre-defined, named query
And
Query createNamedQuery(String name);
The JPA-defined named query creation method. This form can represent an HQL/JPQL query or a native query.
Parameters:
name the name of a pre-defined, named query
It gives the feeling that getNamedQuery()
may not process any kind of query.
For this kind of question, the best way to understand the difference is very often looking into the method implementations.
Implementation of these methods are located in the org.hibernate.internal.AbstractSharedSessionContract
class.
We could see here createNamedQuery()
that relies on buildQueryFromName()
:
@Override
public QueryImplementor createNamedQuery(String name) {
final QueryImplementor<Object> query = buildQueryFromName( name, null );
query.getParameterMetadata().setOrdinalParametersZeroBased( false );
return query;
}
protected <T> QueryImplementor<T> buildQueryFromName(String name, Class<T> resultType) {
checkOpen();
checkTransactionSynchStatus();
delayedAfterCompletion();
// todo : apply stored setting at the JPA Query level too
final NamedQueryDefinition namedQueryDefinition = getFactory().getNamedQueryRepository().getNamedQueryDefinition( name );
if ( namedQueryDefinition != null ) {
return createQuery( namedQueryDefinition, resultType );
}
final NamedSQLQueryDefinition nativeQueryDefinition = getFactory().getNamedQueryRepository().getNamedSQLQueryDefinition( name );
if ( nativeQueryDefinition != null ) {
return (QueryImplementor<T>) createNativeQuery( nativeQueryDefinition, resultType );
}
throw exceptionConverter.convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) );
}
And we could see there getNamedQuery()
that performs itself what buildQueryFromName()
does for createNamedQuery()
:
@Override
public QueryImplementor getNamedQuery(String name) {
checkOpen();
checkTransactionSynchStatus();
delayedAfterCompletion();
// look as HQL/JPQL first
final NamedQueryDefinition queryDefinition = factory.getNamedQueryRepository().getNamedQueryDefinition( name );
if ( queryDefinition != null ) {
return createQuery( queryDefinition );
}
// then as a native query
final NamedSQLQueryDefinition nativeQueryDefinition = factory.getNamedQueryRepository().getNamedSQLQueryDefinition( name );
if ( nativeQueryDefinition != null ) {
return createNativeQuery( nativeQueryDefinition, true );
}
throw exceptionConverter.convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) );
}
To explain the presence of these two methods that looks an undesirable duplication, you have to be aware that createNamedQuery()
comes from the Persistence API (EntityManager
interface more specifically) while getNamedQuery()
is a Hibernate specific method (defined only in the org.hibernate.Session
interface).
And getNamedQuery()
method was defined in very early Hibernate versions.
For example Hibernate 3.0 (released in 2005) had already that.
The specification (JPA
) was released in 2009, so after Hibernate,
doesn't have necessarily keep all Hibernate methods/classes.
Whereas the undesirable duplicated methods (and also in the processing as we could see in their implementation).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With